atldays / laravel-url
Laravel package for URL value objects, sanitization pipelines, browser URL support, validation rules, request macros, and Laravel Data integration.
Requires
- php: ^8.2
- ext-iconv: *
- illuminate/contracts: ^11.0|^12.0|^13.0
- illuminate/http: ^11.0|^12.0|^13.0
- illuminate/support: ^11.0|^12.0|^13.0
- illuminate/translation: ^11.0|^12.0|^13.0
- spatie/laravel-package-tools: ^1.93
- spatie/url: ^2.4
Requires (Dev)
- laravel/pint: ^1.18
- orchestra/testbench: ^9.0|^10.0|^11.0
- phpunit/phpunit: ^11.0|^12.5
- spatie/laravel-data: ^4.20
Suggests
- spatie/laravel-data: Required to use the Data cast and transformer integrations.
This package is auto-updated.
Last update: 2026-04-16 21:16:46 UTC
README
atldays/laravel-url is a Laravel package for working with URLs in a more predictable, framework-friendly way.
At its core, the package builds on top of spatie/url, adds Laravel integration, supports browser-specific schemes, provides sanitizer pipelines for unsafe input, ships validation rules, request macros, and optional integration with spatie/laravel-data.
Why This Package Exists
Working with URLs in real applications is usually messier than simply parsing a clean string.
Inputs may come from:
- request headers such as
OriginandReferer - user-submitted form fields
- browser-specific URLs like
chrome-extension://... - values that contain control characters or broken UTF-8
- DTOs and data objects that need automatic casting
This package gives you a single Laravel-oriented layer for those cases while still relying on the excellent parsing foundation provided by spatie/url.
Features
Atldays\Url\Urlvalue object built on top ofspatie/url- support for browser-specific schemes:
chrome-extension,moz-extension,chrome,opera,edge - URL factory with sanitizer profiles
- configurable sanitizer pipelines
- Laravel facade for short, expressive usage
- validation rules for generic URLs and browser URLs
- request macros for extracting typed URLs from headers
- optional
spatie/laravel-datacasts and transformer - translations for validation messages
Requirements
- PHP
^8.2 - Laravel
^11.0|^12.0|^13.0
Installation
Install the package:
composer require atldays/laravel-url
If you want to customize sanitizer profiles, publish the config:
php artisan vendor:publish --tag="url-config"
If you want to use spatie/laravel-data integration, install it separately:
composer require spatie/laravel-data
Quick Start
Use the facade
use Atldays\Url\Facades\Url; $url = Url::make('https://example.com/path?sort=desc'); $url = Url::make(' "https://example.com/path?sort=desc" ', 'header'); $url = Url::makeOrNull($request->header('origin'), 'header');
Use the factory directly
use Atldays\Url\UrlFactory; $factory = app(UrlFactory::class); $url = $factory->make('https://example.com'); $safeUrl = $factory->makeOrNull($rawValue, 'header');
The URL Value Object
The package provides Atldays\Url\Url, which extends Spatie's URL object and adds Laravel-oriented behavior.
Browser-specific schemes
use Atldays\Url\Url; $url = Url::fromString('chrome-extension://extension-id/options.html'); $url->hasBrowserScheme(); // true
Detect IP hosts
$url = Url::fromString('https://127.0.0.1:8080/ping'); $url->isIpHost(); // true
Get the base URL
$url = Url::fromString('https://example.com:8443/path?x=1'); $url->getBase(); // https://example.com:8443
Factory And Sanitizer Profiles
The recommended entry point for application code is UrlFactory or the Url facade.
Before the URL object is created, the factory runs the input through a configurable sanitizer pipeline.
Default behavior
When you do not pass a profile explicitly, the factory uses the configured default profile:
$url = Url::make($value);
Explicit profile
$url = Url::make($value, 'header');
Available profiles
The package currently ships with two profiles:
defaultGeneral-purpose cleanup for regular application inputheaderCleanup for header values such asOriginandReferer
Built-in sanitizers
HeaderValueSanitizerTrims wrapping quotes and header-specific whitespace noiseControlCharsSanitizerRemoves control characters before parsingUtf8SanitizerNormalizes broken UTF-8 before the final URL object is created
Configuration
use Atldays\Url\Sanitizers\ControlCharsSanitizer; use Atldays\Url\Sanitizers\HeaderValueSanitizer; use Atldays\Url\Sanitizers\Utf8Sanitizer; return [ 'default_profile' => 'default', 'profiles' => [ 'default' => [ ControlCharsSanitizer::class, Utf8Sanitizer::class, ], 'header' => [ HeaderValueSanitizer::class, ControlCharsSanitizer::class, Utf8Sanitizer::class, ], ], ];
You can add your own sanitizer classes as long as they implement:
Atldays\Url\Sanitizers\UrlSanitizer
Validation Rules
The package includes Laravel validation rules for both standard URLs and browser-specific URLs.
Generic URL rule
use Atldays\Url\Rules\Url; Validator::make($data, [ 'website' => ['nullable', new Url()], ]);
This rule:
- supports
nullable - rejects non-string values
- accepts browser-specific URLs
- validates regular web URLs using Laravel-friendly behavior
Browser URL rule
use Atldays\Url\Rules\BrowserUrl; Validator::make($data, [ 'extension_url' => ['nullable', new BrowserUrl()], ]);
This rule only accepts browser-specific schemes such as:
chrome-extension://...moz-extension://...chrome://...edge://...opera://...
Request Macros
The service provider registers a few request macros that return typed URL objects.
getUrlFromHeader
$url = request()->getUrlFromHeader('origin');
getOriginUrl
$origin = request()->getOriginUrl();
getRefererUrl
$referer = request()->getRefererUrl();
getFullUrl
$current = request()->getFullUrl();
These macros:
- parse values through the package factory
- use the
headerprofile when reading headers - return
nullor the provided default when parsing fails - reject header URLs with IP hosts
spatie/laravel-data Integration
If your project uses spatie/laravel-data, the package provides casts and a transformer under src/Data.
UrlCast
Use UrlCast when the incoming value must already be a valid URL.
use Atldays\Url\Data\Casts\UrlCast; use Atldays\Url\Data\Transformers\UrlTransformer; use Spatie\LaravelData\Attributes\WithCast; use Spatie\LaravelData\Attributes\WithTransformer; use Spatie\LaravelData\Data; final class LinkData extends Data { public function __construct( #[WithCast(UrlCast::class)] #[WithTransformer(UrlTransformer::class)] public \Atldays\Url\Contracts\Url|null $url, ) {} }
ToUrlCast
Use ToUrlCast when you want to coerce host-like values into full URLs.
Examples it can handle:
https://example.com/pathexample.com/pathexample.com
use Atldays\Url\Data\Casts\ToUrlCast; final class HostData extends Data { public function __construct( #[WithCast(ToUrlCast::class)] public \Atldays\Url\Contracts\Url|null $url, ) {} }
UrlTransformer
UrlTransformer converts the URL object back to its string representation when the data object is transformed.
Contracts
The package exposes a small set of contracts under Atldays\Url\Contracts, including:
UrlQuerySegmentUrlable
These contracts are useful when you want to type against abstractions instead of the concrete URL implementation.
Translations
Validation messages are provided through the package translation namespace:
url::validation.url url::validation.browser_url
If you want to publish the package translations into your Laravel application and customize them, run:
php artisan vendor:publish --tag="url-translations"
After publishing, you can override the package translations in:
lang/vendor/url
Testing
Run the test suite:
composer test
Check formatting:
composer format:test
Auto-fix formatting:
composer format
Credits
- Spatie URL for the parsing foundation
- Spatie Laravel Package Tools
- Spatie Laravel Data for optional DTO integration
License
The MIT License. Please see LICENSE.md for more information.