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

Countries Laravel Package

savannabits/countries

A Laravel package for adding country, state/region, and city data to your application, with models, migrations, seeders, and helpers for working with location records.

View on GitHub
Deep Wiki
Context7

Getting Started

  1. composer require savannabits/countries
  2. Publish package assets: php artisan vendor:publish --provider="Savannabits\Countries\CountriesServiceProvider" (migrations + config). Confirm the config file (config/countries.php) before migrating.
  3. Run php artisan migrate and seed the package data. Seeding is the heavy step (cities in particular), so run it explicitly rather than as part of a normal db:seed deploy.
  4. Look first at the exported models (Country, Region, City, Currency, Timezone under the Savannabits\Countries\Models namespace) and the package README for the install/seed artisan command for your version.

First use case: populate a country dropdown and resolve a phone/ISO code.

use Savannabits\Countries\Models\Country;

$countries = Country::orderBy('name')->get(['id', 'name', 'iso_2', 'phone_code']);
// Blade: <option value="{{ $c->id }}" data-iso="{{ $c->iso_2 }}">{{ $c->name }}</option>

v1.0.0 adds Laravel 10 support; check your PHP version (Laravel 10 requires PHP 8.1+) and that your other dependencies allow it before upgrading.

Implementation Patterns

  • Reference data is read-mostly. Treat countries/regions/currencies as static lookup tables: cache the arrays (e.g. Cache::remember('countries', ...)) and only bust the cache after re-seeding.
  • Relationship traversal: Country -> regions -> cities. Always eager-load (Country::with('regions')) when rendering cascading address forms; otherwise you get an N+1 per country.
  • Cascading selects: drive the state/region dropdown off country_id via an AJAX endpoint returning regions, and the city dropdown off region_id. Seed only the regions/cities you actually operate in if you don't need global coverage.
  • Validation: validate against ISO codes (exists:countries,iso_2) rather than display names; store the stable code and resolve the label at render time. Same for currency/timezone.
  • Model swapping: keep package model usage behind your own service/repository (or a config-driven model binding) so you can swap in a custom Country model later without touching views/controllers.
  • Seeding in CI/CD: make seeding an idempotent, separate artisan step (e.g. in a deploy script) rather than inside migrations, so re-runs and rollbacks stay predictable.
  • Address/checkout integration: combine country + region + city IDs on your addresses table, with foreign keys where it's useful and plain iso_2 strings where you want to decouple from package tables.
  • Localization: use the ISO code to look up translations from your own lang/ files rather than relying on the package's English names.

Gotchas and Tips

  • Seeding volume: city data is large and will noticeably slow deploys and test suites. Prefer a subset or run the seed once out-of-band; consider migrate:fresh --seed only in local env.
  • Publish before migrate: if the config/migrations aren't published first, table names and defaults can differ from what your code expects. Publish, read the config, then migrate.
  • Namespace/version drift: this is a v1.0.0 with Laravel 10 support. Older Laravel/PHP combos may need to stay on a prior tag; pin savannabits/countries explicitly and run composer why-not savannabits/countries 1.0.0 if the upgrade stalls.
  • Config table names: if you rename tables in countries.php, update any raw queries and foreign keys in your own migrations.
  • Cache staleness: if you cache country/currency lists, add a post-seed cache flush; otherwise a re-seed silently leaves stale data serving traffic.
  • Indexes: ensure iso_2, iso_3, phone_code, and foreign keys (country_id, region_id) are indexed; lookups by code happen on every form render.
  • Lookups by code, not name: names are not unique and get translated; join and filter on ISO codes.
  • Timezones: don't assume the package timezone list matches PHP's DateTimeZone::listIdentifiers() exactly; validate before passing to Carbon/DateTimeZone.
  • Debugging: a missing/empty result is almost always "did you seed?" rather than a query bug — verify row counts (Country::count()) before chasing the code.
  • Extension points: keep seed data version-controlled via your own seeder wrapper, and wrap package models behind your own layer so a future breaking change (model rename, namespace move) is a one-file change rather than a codebase-wide search.
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.
frankyso/ipaymu
3mdikram/worldmoneywords
snowsoft/config
itmosoft/laravel-subscriptions
larva/laravel-ai-qwen
diephp/sequences
users-au/socialite-provider
twidpay/twid-logger
mrnewport/laravel-plaid
mrnewport/laravel-repo
mrnewport/laravel-docsign
mrnewport/laravel-stow
mrnewport/laravel-flow
mrnewport/laravel-priceable
mrnewport/laravel-nestedterms
fredmeng/laravel-apidoc-generator
itstructure/laravel-multilingual-tools
pdustdar/elasticsearch
markupai/php-sdk
rlacerda83/lumem-microservice-shipment