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

Addressing Laravel Package

markup/addressing

Address management for Laravel: store, format, and validate postal addresses with country and subdivision data, polymorphic address models, and helpers for clean, consistent address handling across your application.

View on GitHub
Deep Wiki
Context7

Getting Started

  • Install with composer require markup/addressing. There is no Laravel service provider, facade, config file, or auto-discovery — it is a plain, framework-agnostic PHP library, so nothing appears in config/app.php and nothing is published.
  • Read in this order: the README.md usage block, then src/ to confirm the exact class names and namespace (Markup\Addressing\…), then tests/. The test fixtures are the most reliable documentation of what each formatter actually emits, since the README is thin and the package has had no release since 2019-04-15.
  • Expect the shape to be: an address value object holding recipient/street/locality/postal-code/country fields, plus one or more formatter classes that turn that object into a string (or an array of lines). Verify signatures against src/ before copying any snippet — this package is old enough that blog examples and its own docs may not match the code.
  • First use case: rendering a shipping or billing address on an order confirmation, invoice PDF, or transactional email, where the correct line order and punctuation differ by destination country (e.g. US City, ST ZIP versus GB Street / City / POSTCODE versus JP, which orders from large to small).
  • Minimal smoke test before wiring it into the app:
// Confirm namespace and constructor signature in src/ first.
$address = new Address(
    'Jane Doe',
    '10 Downing Street',
    'London',
    'SW1A 2AA',
    'GB'
);

$formatter = new SomeCountryFormatter(); // see src/ for concrete classes
echo $formatter->format($address);

If that renders the expected multi-line block, the package is doing its one job and you can proceed to integration.

Implementation Patterns

Store structured, render at the edge. The single most important pattern: persist the discrete address fields (or a JSON column) on your orders/addresses tables and call the formatter only at the moment of display. Never persist the formatted string — you will eventually need a different format for a shipping label than for a customer-facing invoice, and reformatting stored text is not possible.

Formatter selection by country code. The library gives you formatters; the routing between them is your job. Keep a small factory or registry:

class AddressFormatterFactory
{
    public function for(string $countryCode): AddressFormatterInterface
    {
        return match (strtoupper($countryCode)) {
            'US' => new UnitedStatesFormatter(),
            'GB' => new UnitedKingdomFormatter(),
            // ...
            default => new GenericFormatter(),
        };
    }
}

Always ship a sensible default. An unmapped country should degrade to a generic "street / city / region / postal code / country" layout, never throw in a checkout confirmation email.

Bind it once in Laravel. Register the factory as a singleton in AppServiceProvider::register() and inject it, rather than new-ing formatters in controllers. Because the package has no container integration, this is the only wiring you need:

$this->app->singleton(AddressFormatterFactory::class);

Wrap it behind your own interface. Define App\Contracts\AddressFormatter with a single format(Address $address): string method and adapt the package inside. Given the package's age (see Gotchas), this one-file indirection is what makes a future swap to a maintained library cheap.

Map Eloquent models to the value object. Add a toAddressObject() method or a small mapper class on your Address model. Keep the mapping in one place so nullable columns (address_line_2, region) are normalized to null or '' consistently — formatters are sensitive to the difference.

Blade component for the view layer.

<x-address :address="$order->shippingAddress" :locale="$order->locale" />

The component resolves the factory, picks the formatter from $address->country_code, and renders {!! nl2br(e($formatted)) !!}. Escaping matters: postal addresses occasionally contain & and quotes.

API responses. Return both the structured fields and a pre-rendered convenience field:

return [
    'shipping_address' => $address->toArray(),
    'shipping_address_formatted' => $formatter->format($address),
];

Structured fields let clients re-render for their own locale; the formatted string saves mobile clients from reimplementing the rules.

Test with golden files. Because output is deterministic string formatting, a data-provider test asserting exact expected strings per country is the highest-value test you can write. Cover at minimum: a fully populated address, an address with a null second line, an address with no postal code (several countries legitimately have none), and an unmapped country falling back to the generic formatter.

Gotchas and Tips

  • It is effectively unmaintained. Last release 2019-04-15, one star, zero dependents on Packagist. There will be no security patches, no PHP 8.4 fixes, and no response to issues. Treat it as vendored code: pin an exact version in composer.json and be prepared to fork it into your own VCS if you need a change. The low dependent count also means bugs are unlikely to have been shaken out by other users.
  • PHP version constraints will bite. A 2019 package very likely declares "php": "^7.x" in composer.json. On modern PHP the install fails. composer require --ignore-platform-reqs will force it in, but do that only after verifying the code actually runs — deprecated dynamic properties and removed each()-era functions are real risks. Better: fork, bump the constraint, run its test suite.
  • Check the source for the class names. There is no stable, widely-known API surface here and almost no community examples, so treat src/ as the source of truth over any README, snippet, or AI-generated sample (including the ones above).
  • No container integration. Nothing is auto-discovered. If a Markup\Addressing\AddressingServiceProvider is referenced anywhere online, it does not exist in this package.
  • Formatting is not validation. Do not use the formatters to check whether a postal code is correct or an address is deliverable. They only arrange strings. Use a dedicated validation/deliverability service for that, and validate before formatting.
  • Sparse addresses produce ugly output. Most formatters join lines and fields with a delimiter and assume every field is populated. A null region can yield London, , SW1A 2AA or a blank line. Sanitize on the way in, and add a test for every optional field being absent.
  • Labels are likely hardcoded English. Strings like "Postal code" or "State" are typically baked into the formatter. If you need localized labels, wrap the output with your own translation layer or render the lines array yourself with translated keys.
  • Country data is static and frozen at 2019. Country names, and any administrative-division lists bundled in, will not reflect later changes. For country names specifically, prefer symfony/intl or Laravel's own Countries helpers over anything shipped here.
  • Debug at the line level, not the string level. If output looks wrong, dump the intermediate array of address lines rather than the final joined string — it immediately shows whether the bug is in field selection or in the joining logic.
  • Extension point: implement the package's formatter interface for countries that aren't covered, or decorate an existing formatter to tweak spacing/punctuation while keeping its field ordering. That is usually cheaper than editing the vendor code.
  • Strongly evaluate the alternative before committing. commerceguys/addressing is the de facto standard for this problem: actively maintained, backed by CLDR country data, integrates with symfony/intl, and handles the empty-field and localization cases above properly. Given that a typical integration touches one or two call sites, migrating is usually cheaper than living with the constraints. If you keep markup/addressing, the wrapper interface described in Implementation Patterns is what keeps that door open.
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.
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
uni-method/symfony-lib