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

Iso Countries Laravel Package

vanaboom/iso-countries

ISO countries for Laravel: a lightweight package providing ISO 3166 country codes, names, and lookup helpers for building selects, validating input, and localizing addresses.

View on GitHub
Deep Wiki
Context7

Getting Started

The package is a data-and-helpers library, not an application scaffold, so the entire "setup" is usually one require plus one config publish:

composer require vanaboom/iso-countries
php artisan vendor:publish --tag=iso-countries-config

Nothing to migrate in most cases — the country dataset ships as static PHP/JSON data inside the package. If the release notes for the version you install mention a migration or a publishable seeder, treat that as the exception and confirm in the changelog before assuming it is data-only.

Where to look first, in order:

  1. README.md — the resolution order for names/translations and the public entry point (facade vs. helper vs. injected service) are the two things that dictate every subsequent call site.
  2. config/iso-countries.php — locale, default country, and any "extra" or overridden entries. This is the only file you should be editing.
  3. src/ — specifically the data source class and any Rules/ directory. If there is a validation rule class, adopt it immediately; if not, you will be hand-rolling Rule::in(...).

The first real use case is almost always deleting a hardcoded country array from a registration form and replacing it with a package-driven list. Do that one controller/one Blade partial first, because it forces you to answer the questions that bite later: which code format am I storing (alpha-2 or alpha-3), am I rendering translated names, and is the list sorted by name or by code.

Implementation Patterns

Dropdowns and select inputs. Fetch the collection once, map to [code => name], and let the view iterate. The pattern that survives review is to resolve the list in a form request, view composer, or dedicated CountryOptions class rather than calling the package inline in Blade — the inline call is fine once and painful when you need translated, sorted, and filtered in three different places.

// app/Support/CountryOptions.php
public function forSelect(?string $locale = null): array
{
    return IsoCountries::all($locale)      // confirm exact signature in README
        ->sortBy('name')
        ->pluck('name', 'alpha2')
        ->all();
}

Validation. Pair the select's value with the package's rule if one exists; otherwise constrain explicitly rather than trusting the model:

$request->validate([
    'country' => ['required', 'string', 'size:2', new CountryRule()],
]);

Normalize case before validation (strtoupper()), not inside the rule — form submissions arrive as gb, GB, and Gb, and a rule that silently accepts all three will let inconsistent data into the column.

Storage and API boundaries. Store the canonical code (usually alpha-2, char(2)) in the database and resolve the display name at render time. Do not denormalize the country name into the user row — it freezes the translation and breaks when the dataset updates. On the API side, emit {"code": "DE", "name": "Germany"} from a resource class so clients are not forced to call the package themselves.

Seeding reference tables. If you have a countries table (for joins, flags, or geo lookups), seed it from the package inside a dedicated seeder and make it idempotent with upsert on the code column. That gives you a re-runnable db:seed --class=CountrySeeder after each package bump, which is the cheapest way to absorb upstream dataset changes.

Localization. Keep the app locale and the package locale decoupled. Pass the locale explicitly at the call site when rendering a user's preference rather than relying on app()->getLocale(), otherwise queue workers and API requests (which often run under a default locale) will produce names in the wrong language.

Gotchas and Tips

  • Alpha-2 vs alpha-3 ambiguity. This is the number one source of silent bugs. Two packages and two columns in the same app will drift. Pick one canonical format, name the column after it (country_code → char(2)), and add a cast or accessor that normalizes on write.
  • Case sensitivity in lookups. find('de') may return null while find('DE') works, depending on whether the package keys its dataset by uppercase code. Normalize input at the boundary; do not patch the package.
  • Config caching. php artisan config:cache in deploy pipelines will freeze published config. If you added country overrides to the config file, they are safe; if you were relying on runtime config([...]) mutation in a service provider, they will vanish in production and only there.
  • Dataset staleness after upgrade. v1.1.0 arrives via a changelog-only release note, so diff the data files (git diff 1.0.1..v1.1.0 -- src/ resources/) before deploying. Country name changes and code reassignments are rare but real, and they can orphan foreign keys or break assertions in tests that hardcode 'Macedonia'.
  • Testing. Snapshot-test the option list (assertCount, spot-check a few codes) rather than asserting the full translated array. A full-array assertion turns every package bump into a test rewrite with no signal about whether anything actually broke.
  • Extension points. If the dataset lacks something you need — EU membership, phone prefixes, continent grouping — prefer a thin wrapper class in app/Support that decorates the package collection over forking. If the package exposes a "custom/extra entries" config key, use that for a handful of overrides; do not use it as a place to park a second dataset.
  • Debugging. When a lookup returns null, the culprit is nearly always the input format or a locale with no translation fallback — dump the raw collection keys once before assuming the package is broken.

Given that the v1.1.0 notes are only a changelog URL, verify before upgrading whether the release touched the public method signatures or the data format; if either changed, run your option-list and validation tests against the new version on a branch first.

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.
abbasudo/artisan-route
mirvan/ippanel
ignibyte/aic-framework
glavweb/data-schema-bundle
glavweb/datagrid-bundle
tacticmedia/scim-server
uni-method/frame
neika-ai/sdk
adachsoft/php-code-style
pharaonic/laravel-notification-dependencies
beautinow/translug
dev-brainiac/bot-cloaked
octoberrain/html
octoberrain/extension
octoberrain/exception
octoberrain/contracts
adachsoft/api-version-bundle
cgv/localized-resource
noith/settings
kda/laravel-package