Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

World Clock Laravel Package

naif/world-clock

A Laravel package for adding world clocks to your app. Display current local times for multiple cities or timezones, convert between zones, and configure clock labels and formats with simple, reusable Blade components.

View on GitHub
Deep Wiki
Context7

Getting Started

This is a Laravel Nova card, not a general Laravel package — it renders a dashboard/panel widget showing the current time in one or more cities. Nothing happens unless Nova is installed and the card is registered.

  1. Install into a Nova-enabled app:
composer require naif/world-clock
  1. Register the card in app/Providers/NovaServiceProvider.php, inside cards():
use Naif\WorldClock\WorldClock;

public function cards()
{
    return [
        // ... your other cards
        (new WorldClock)->timezones([
            'America/New_York',
            'Europe/London',
            'Asia/Riyadh',
        ]),
    ];
}
  1. Hard-refresh the Nova dashboard (/nova). If the card appears blank, you have an asset-registration problem, not a config problem — see Gotchas.

Where to look first. Read these three files in the vendor directory before writing any code, because the fluent API surface is small and undocumented:

  • vendor/naif/world-clock/src/WorldClock.php — the card class; every public function here is a chainable config method.
  • vendor/naif/world-clock/src/CardServiceProvider.php (or WorldClockServiceProvider.php) — tells you the component name and whether Nova::script() / Nova::style() are wired up.
  • vendor/naif/world-clock/resources/js/card.vue — tells you the exact prop names the frontend expects, which is what withMeta([...]) must match.

First real use case. "We have offices in three timezones and I keep opening worldtimebuddy during standups." Put one card on the main dashboard with two or three cities, confirm the times match date in a shell, then move on to per-user or per-team variants.

Implementation Patterns

Fluent configuration in cards(). The idiomatic Nova pattern is to configure the card where you register it, so environment/tenant differences live in one file:

public function cards()
{
    return [
        (new WorldClock)->timezones([
            'America/Los_Angeles',
            'Europe/Berlin',
            'Asia/Tokyo',
        ])->width('1/2'),
    ];
}

Nova's built-in ->width(), ->onlyOnDashboards(), ->canSee() and ->canRun() all work on any Card subclass, so you rarely need package-specific placement logic.

Fallback pattern when the fluent API is missing. Since the package is old and thinly documented, withMeta() is your escape hatch — anything in the meta bag arrives as a Vue prop:

(new WorldClock)->withMeta([
    'timezones' => ['America/New_York', 'Europe/London'],
    'label'     => 'Team hours',
])

Verify the key names against card.vue; a mistyped key fails silently.

Per-user timezones. Cards are resolved per request, so $request->user() is available and you can drive the list from user settings — a nice upgrade over a hardcoded list:

(new WorldClock)->timezones(
    collect($request->user()->watched_timezones ?? ['UTC'])
        ->prepend(config('app.timezone'))
        ->unique()
        ->values()
        ->all()
)

Multiple cards instead of one big card. If you want "US team" and "EU team" side-by-side with distinct widths, register two WorldClock cards. Nova renders each independently and you avoid fighting the Vue component's internal layout.

Resource detail pages. Cards are usually dashboard-only, but Laravel\Nova\Card can be attached to resource screens via Nova::resourcesFor()/panel definitions. If you want a clock on a specific resource, be aware the card refreshes only on page navigation — it is not a live element (see Gotchas).

Customization path. The package is 6 stars, MIT, last released 2019, zero dependents. Treat it as a vendored starting point: the realistic long-term pattern is to copy resources/js/card.vue + dist/js/card.js into your own nova-components/WorldClock and own it via php artisan nova:card. That takes an afternoon and removes the maintenance question entirely.

Gotchas and Tips

  • Nova version compatibility is the big one. Last release 2019-03-20 means it targets the Nova 1.x/2.x asset pipeline (Nova::script() with a prebuilt dist/js/card.js). Nova 4 moved to Vite-built cards; the old compiled bundle often still loads, but Vue 2 → Vue 3 differences can break the component. Test on the exact Nova major you run before committing.
  • "Card is blank / Unknown custom element". Almost always asset registration. Check that the service provider is auto-discovered (composer dump-autoload, confirm extra.laravel.providers in the package's composer.json), then check the browser console for a 404 on card.js. php artisan nova:publish and php artisan view:clear fix most stale-asset cases.
  • Timezone validity is silent. Timezone strings are passed straight to the JS side; an invalid entry like 'EST' or a typo'd 'Europe/Berln' usually renders blank or Invalid Date rather than throwing. Always use IANA names (Continent/City). The authoritative list is php -r 'print_r(DateTimeZone::listIdentifiers());'.
  • DST and "server vs client time" confusion. The card computes local time in the browser. If your Nova users span regions this is correct behavior; don't try to precompute times server-side and pass strings — you'll reintroduce the bug you're trying to display.
  • It is not a live clock. Unless the Vue component happens to run a setInterval, the time is frozen at page load. Don't put it on a wall-mounted dashboard and expect it to tick; if liveness matters, add a setInterval(() => this.now = new Date(), 1000) in the component and rebuild assets.
  • Dark mode. Nova 3+/4 dark themes can wash out hand-picked colors. If text is invisible, the component has hardcoded styles — override via the card's CSS or edit the compiled assets.
  • Config publishing. There may be no config file at all. Don't run php artisan vendor:publish blindly hoping for options; list the package's publish groups first (php artisan vendor:publish interactive menu) or read the service provider's publishes() calls.
  • Debugging tip. In the browser devtools, inspect the card element and read the Vue props directly. That confirms whether your PHP-side configuration actually reached the frontend — it separates a PHP/config bug from a JS rendering bug in one step.
  • Extension points. Anything not exposed fluently can be reached with withMeta(). Beyond that, subclass and override the component or jsonSerialize():
class TeamClock extends WorldClock
{
    public function component()
    {
        return 'team-clock'; // your own rebuilt component
    }
}
  • Bus factor. No dependents, one maintainer, stale since 2019, MIT. Pin the version in composer.json, and if you rely on it for anything visible to stakeholders, plan to fork.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
unabomber/timezone
delatbabel/contacts
astritzeqiri/g-recaptcha
kevinongko/laravel-genode
developeruz/laravel-analytics
robbiep/afterthedeadline
frankkessler/incontact-laravel-oauth2-rest
jlxh/laravel-userlog
davidmgilo/timetables
qylinfly/role-permission
reflect-digital/conduit
takashato/laravel-vietqr
aitor24/laralang
kraenzle-ritter/entity-relations
dindigital/din-image
pomirleanu/image-colors
sawmainek/laravel-api-generator
delatbabel/jsonresponses
mouhamedfd/permissions-generator
eduplus/qr