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

Nova Laravel World Laravel Package

seche/nova-laravel-world

A Laravel Nova package that brings world geographic data into your admin panel, with fields and resources for working with countries, states, and cities.

View on GitHub
Deep Wiki
Context7

Getting Started

This is a reference-data package (countries, calling codes, divisions/regions, cities, and localized city names). The 1.0.1 release is bug-fix only — no new API surface — so treat it as the first stable baseline to build against rather than a feature upgrade.

  1. Require it and confirm you get 1.0.1 or later:
    composer require <vendor>/<package>:^1.0
    
    1.0.0 shipped with a trailing comma in composer.json, which can break parsing/installation in stricter Composer versions. If you saw a composer.json parse error or were pinned to 1.0.0, upgrade immediately.
  2. Publish whatever is publishable (config, migrations, seeders) and inspect the migration/seed order before running:
    php artisan vendor:publish --provider="<Vendor>\<Package>\<Package>ServiceProvider"
    php artisan migrate
    
  3. Seed the reference data. This package is only useful once the tables are populated — an empty countries table is the most common "it's broken" report.
  4. Look first at the models (Country, Division, City, CityLocale) and their relationships. That is the real documentation; the README tends to be thinner than the schema.

First use case: a country dropdown backed by calling codes for a phone input, plus a city selector filtered by division:

$countries = Country::orderBy('name')->get(['id', 'name', 'iso2', 'callingcode']);

// In a Blade/Inertia form
<select name="country_id">
    @foreach ($countries as $country)
        <option value="{{ $country->id }}" data-calling-code="{{ $country->callingcode }}">
            {{ $country->name }} (+{{ $country->callingcode }})
        </option>
    @endforeach
</select>

Implementation Patterns

Store foreign keys, not display strings. Persist country_id / city_id (or ISO codes if the package exposes them as stable keys). Names and calling codes change; IDs and ISO codes don't. This also makes the 1.0.1 column fix a non-event for your data.

Wrap lookups in a repository or cached service. Reference data is read-heavy and effectively static. Cache the country list and per-country city lists with a long TTL and bust the cache only when you reseed:

class GeoRepository
{
    public function countries(): Collection
    {
        return Cache::rememberForever('geo.countries', fn () =>
            Country::orderBy('name')->get(['id', 'name', 'iso2', 'callingcode'])
        );
    }

    public function citiesFor(int $countryId): Collection
    {
        return Cache::remember("geo.cities.{$countryId}", now()->addDay(), fn () =>
            City::where('country_id', $countryId)->orderBy('name')->get()
        );
    }
}

Eager-load the chain before displaying localized city names. CityLocale::display() needs the city and its division; lazy loading that per row is a classic N+1 in city lists:

$cities = City::with(['division', 'locales'])->where('country_id', $id)->get();

$label = $city->localeFor(app()->getLocale())?->display();

Validate against the package, not against a hardcoded list. Use exists:countries,iso2 (or a small custom rule hitting the cached repository) in Form Requests. For phone numbers, derive the expected calling code from the selected country and compare, rather than shipping your own country table.

API resources over raw models. The tables carry columns (calling codes, locale rows) that are internal detail. Shape the payload explicitly so a future package migration doesn't silently change your public API.

Localization flow: pick the locale row in this order — exact match on app()->getLocale(), then a configured fallback (e.g. en), then the plain city name. Put that resolution in one place; don't repeat ?? chains across views.

Integration tip: if you only need countries and calling codes, don't migrate/seed the city and locale tables. Smaller footprint, faster CI, fewer moving parts to keep in sync.

Gotchas and Tips

  • The 1.0.1 typo fix is a breaking change for workarounds. The calling-code column name was misspelled in 1.0.0. If you wrote ->calling_code, a raw selectRaw, or a query referencing the old name, it will now fail. Grep your codebase for the old column before upgrading, and remove any as aliases you added to paper over it.
  • CityLocale::display() now tolerates a null division. Previously it threw when Division Name was empty. The new behaviour returns a partial/possibly odd-looking string rather than erroring. Don't treat "no exception" as "correct output" — decide explicitly whether a city with no division should render as "City" or "City, Region" with a placeholder, and test with a deliberately division-less city.
  • Reference data doesn't self-update. Bug-fix releases can correct data as well as code. After any upgrade, re-run the seeders in a local/staging environment and diff row counts and a few known records; don't assume your production tables picked up corrections.
  • Seeding is not idempotent by default. Wrap reseeds in a transaction, and check whether the package uses updateOrCreate or plain insert before running against a populated database. If it's insert, truncate first or you'll get duplicate-key failures.
  • callingcode is a string, not an int. Country codes with leading zeros and multi-digit codes will bite you if you cast to integer or compare with == against a numeric input. Normalize by stripping + and whitespace on both sides.
  • Division is nullable. Treat division_id as optional everywhere: in validation (nullable|exists:divisions,id), in UI (don't require a region for countries that don't use them), and in display logic.
  • Extension points: publish and edit the models if you need extra scopes (e.g. scopeActive, scopeWithCallingCode); publish the config for locale fallback and table name overrides; override the display formatter in a subclass rather than editing vendor files so future patch releases stay clean.
  • Debugging checklist for "wrong country/city shown": (1) is the table seeded, (2) is your cache stale after a reseed, (3) is the locale falling back to a row you didn't expect, (4) are you comparing a string code to an integer. Those four cover most reports with this package.
  • Pin with a caret, commit your lockfile. 1.0.x is patch-only and low-risk, but the column-name fix shows that even patch releases can break code that compensated for a bug. Upgrade deliberately, run your geo-related tests, then deploy.
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.
robertmarney/lara-hierarchial-collections
simonschaufi/rule-doc-generator
emissaoja/emissaoja
blackbricksoftware/gravityforms-civicrm-form-processor
al-rahabi/fancy-crud
jinas/dhivatar-component
mltstephane/laravel-quality
bernskiold/laravel-talentlms
bernskioldmedia/laravel-form-architect
youbar/easy-crud
c-point-labs/laravel-hostyourai
dbravoan/dbcms-admin-theme-dbcms
dbravoan/dbcms-theme-db-cyber
dbravoan/dbcms-blocks-basic
dbravoan/dbcms-module-content-audit
dbravoan/dbcms-module-ai-assistant
paygate-to/paygate-php
padosoft/askmydocs-connector-base
defstudio/supercharged-carbon
bernskioldmedia/laravel-matomo