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

Tld Checker Laravel Package

arubacao/tld-checker

Validate top-level domains and email addresses in Laravel. Check whether a TLD exists, support generic and country-code domains, and reject emails with invalid or misspelled TLDs using a bundled, updatable TLD list—no external API calls required.

View on GitHub
Deep Wiki
Context7

Getting Started

arubacao/tld-checker answers one narrow question: does the domain part of a string end in a real, IANA-registered top-level domain? It is a typo-catcher, not a domain validator, and that framing should drive where you put it in your codebase.

Install and go:

composer require arubacao/tld-checker

Package discovery registers the service provider and the Tld facade, so there is nothing to publish or configure for the common case. The canonical first use is registration and profile-update forms, where a mistyped TLD (gmail.con, gmial.cm, company.ocm) is the single most common email error you can catch cheaply and locally:

use Arubacao\TldChecker\Facades\Tld;

Tld::check('[email protected]');   // true
Tld::check('[email protected]');   // false

Look at the package source (src/) and the bundled TLD list before you build on it. Confirm two things: (1) the exact facade alias shipped in your installed version, and (2) whether the TLD list is a static data file bundled with the release or fetched at runtime. The answer to (2) determines your whole operational story — see Gotchas.

Release 1.2.70 adds PHP 8.0 support. If you are on 8.0, this is the first version you can install; if you are on 7.4 you are pinned to 1.2.69 and below. There is no API change in this release, so an upgrade is a composer update with no code edits.

Implementation Patterns

Wrap it in a validation rule. This is the highest-leverage integration — one rule, reused across registration, invitations, and admin-created accounts.

namespace App\Rules;

use Arubacao\TldChecker\Facades\Tld;
use Closure;
use Illuminate\Contracts\Validation\ValidationRule;

class ValidTld implements ValidationRule
{
    public function validate(string $attribute, mixed $value, Closure $fail): void
    {
        $domain = str_contains($value, '@')
            ? substr(strrchr($value, '@'), 1)
            : $value;

        if (! Tld::check($domain)) {
            $fail('The :attribute has an unrecognised top-level domain. Check for a typo.');
        }
    }
}

Pair it with Laravel's built-in rules rather than replacing them — the package does not verify syntax, DNS, or the local part:

'email' => ['required', 'string', 'email:rfc', 'max:255', new ValidTld],

Warn, don't hard-block, in the user-facing path. A TLD-only check will reject any brand-new gTLD if your bundled list predates it. For consumer signups, treat a failure as a confirmation prompt ("Did you mean acme.com?") rather than an outright rejection; for internal/back-office tools and email-list imports, a hard reject is fine and saves you a lot of dirty data.

Normalise before you check. The checker is a suffix comparison, so casing, whitespace, and trailing dots will bite you:

$domain = strtolower(rtrim(trim($domain), '.'));

Isolate it behind your own service if you use it in more than a couple of places. You will want to swap in a real public-suffix resolver later (registrable-domain checks, co.uk-style handling), and a one-line wrapper means that is a single-file change instead of a grep.

Testing. Because the check is a pure local lookup, you can assert against it directly in feature tests without mocking — just be aware your fixtures are pinned to the TLD list of the installed version. For unit tests of downstream logic, mock the facade (Tld::shouldReceive('check')->andReturn(true)) so a future composer update cannot break unrelated tests.

Gotchas and Tips

It validates the TLD, nothing else. Tld::check() will happily pass strings that are not domains at all, provided they end in a real suffix. Never use it as your only guard — email:rfc or url/regex still does the heavy lifting. Think of it as an additional filter, not a substitute.

Stale list is the main failure mode. TLDs are added by ICANN several times a year. Because the data ships with the package, "we support new gTLDs" means "we ran composer update recently." Put the package in your regular dependency-refresh cadence, and if you find .dev-style or newly delegated suffixes being rejected in production, check the installed version before filing a bug. If your install turns out to fetch the list over the network instead, that changes the calculus — add caching, a timeout, and a fallback so a network blip never blocks a signup.

Internationalised domains. münchen.de and its punycode form xn--mnchen-3ya.de are different strings. Normalise with idn_to_ascii($domain, IDNA_DEFAULT, INTL_IDNA_VARIANT_UTS46) before checking, and make sure ext-intl is installed in your container — it is easy to have locally and miss in production.

It is not a public-suffix list. example.co.uk and foo.github.io are treated at the TLD level only. If you need "is this a registrable domain," add a PSL package; do not stretch this one.

Do not use it for trust or risk decisions. A valid TLD says nothing about deliverability, disposability, age, or reputation. Blocking .xyz or .top via this package is trivially bypassed and will also block legitimate users.

Config caching. If you do publish a config file, remember php artisan config:cache in your deploy — a changed config value silently not applying is the classic symptom.

The 1.2.70 takeaway. PHP 8.0 support is a maintenance signal, not a feature: the package is still being kept alive rather than abandoned. Before you upgrade in a Laravel 10/11 app, check the illuminate/support constraint in composer.json — the PHP floor and the Laravel ceiling move independently, and 1.2.70 only guarantees the former.

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.
pharaonic/laravel-notification-dependencies
beautinow/translug
dev-brainiac/bot-cloaked
octoberrain/html
octoberrain/extension
octoberrain/exception
octoberrain/contracts
frankyso/ipaymu
3mdikram/worldmoneywords
snowsoft/config
itmosoft/laravel-subscriptions
larva/laravel-ai-qwen
adachsoft/api-version-bundle
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core