European license plate validator (Russia excluded).Syntax-only validation via regex for multiple EU/EEA countries including Italy, UK, Germany, France, Spain and more.Supports Node.js (TypeScript package) and PHP library.
npm install @codecorn/euro-plate-validator> ๐ European license plate validator (Russia excluded). Multi-country, regex-based validation for EU/EEA license plates. Works in Node.js, TypeScript, and the browser (with a lightweight UI client).
 
---
    
     !module !cdn 
---
- โ
Multi-country support (25+ EU/EEA)
- ๐ซ Russia excluded by design
- ๐ Normalizes input (spaces, hyphens, case)
- ๐ง Smart regex engine per-country (car/motorcycle aware)
- ๐งฉ Lightweight client SDK with UI, flags, dropdown, and Inputmask integration
- โ๏ธ Accepts lowercase input, auto-coerced to UPPERCASE by mask token L
- ๐ Built-in i18n: IT and EN
- ๐งฏ Safe dependency autoload via CDN with configurable overrides
---
``bash`
npm install @codecorn/euro-plate-validator
---
> Use versioned URLs to avoid stale CDN caches.
- ESM (browser) https://cdn.jsdelivr.net/npm/@codecorn/euro-plate-validator@1.0.14/dist/browser/index.esm.js
- IIFE (global window.EuroPlateValidator) https://cdn.jsdelivr.net/npm/@codecorn/euro-plate-validator@1.0.14/dist/browser/index.iife.min.js
- ESM https://cdn.jsdelivr.net/npm/@codecorn/euro-plate-validator@1.0.14/dist/client/index.mjs
- CJS (Node) https://cdn.jsdelivr.net/npm/@codecorn/euro-plate-validator@1.0.14/dist/client/europlate.client.cjs
- https://cdn.jsdelivr.net/npm/@codecorn/euro-plate-validator@1.0.14/dist/assets/css/styles.cssโฆ/assets/css/styles.css
- (compat alias)
---
`ts
import { validatePlate } from "@codecorn/euro-plate-validator";
// Italy (car)
validatePlate("AB 123 CD", ["IT"], { vehicleType: "car" });
// โ { isValid: true, matches: [{country:"IT", name:"Italy"}], checked:["IT"] }
// UK vs IE
validatePlate("AB12 CDE", ["UK", "IE"]);
`
---
The browser client auto-generates a full UI (flag + input + dropdown + status) or attaches to an existing . ecco la versione EN tradotta 1 : 1 . Ho lasciato il codice invariato , e ho applicato lo spazio prima / dopo la punteggiatura solo al testo in prosa .
---
`ts
import { validatePlate } from "@codecorn/euro-plate-validator";
// IT (car)
validatePlate("AB 123 CD", ["IT"], { vehicleType: "car" });
// โ { isValid: true, matches:[{country:"IT", name:"Italy"}], checked:["IT"] }
// UK vs IE
validatePlate("AB12 CDE", ["UK", "IE"]);
`
---
The client either generates the markup ( flag + input + country dropdown + status ) or attaches to an existing input .
`ts
type EuroPlateOptions = {
// DOM
input?: HTMLInputElement; // external input
wrapper?: string | HTMLElement | false; // if provided โ auto-build UI
inputId?: string; // default: derived ( e.g., "epv-xxxx-plate" )
inputName?: string; // default: same
preserveInputAttrs?: boolean; // NEW: if true, does NOT overwrite existing id/name
autoFocusOnInit?: boolean; // NEW: default false ( no focus on init )
// โ๏ธ UI configuration ( new: EVERYTHING under "ui" )
ui?: {
/**
* Where to show the status :
* - "block" โ uses
/* Icon type for inline status ( ignored in "block" and "off" ) /
statusIcon?: "none" | "icon" | "pill"; // default: "none"
/* Whether to show status text /
showStatusText?: boolean; // default: blockโtrue , inlineโfalse
/* Inline icon position /
iconPosition?: "right" | "left"; // default: "right"
// Optional references to existing nodes ( when NOT using wrapper )
flagIcon?: HTMLElement;
flagLabel?: HTMLElement;
dropdown?: HTMLElement;
button?: HTMLElement;
status?: HTMLElement;
};
// UX / i18n
mode?: "AUTO" | string; // fixed country or AUTO ( default )
i18n?: "AUTO" | "IT" | "EN"; // default AUTO โ navigator it / en
allowedCountries?: string[]; // whitelist ; default : all
vehicleType?: "any" | "car" | "bike"; // default : any
placeholders?: { auto?: string }; // placeholder for AUTO
// Normalization / formatting
normalize?: (code: string) => string; // default GBโUK
formatters?: Record
// Timings
timings?: { debounce?: number; clear?: number };
// Dependencies / logging
deps?: { inputmask?: any }; // manual inject ( e.g., window.Inputmask )
autoLoadDeps?: { inputmask?: boolean }; // default : true ( autoload UMD )
cdn?: { inputmask?: string }; // override Inputmask CDN URL
logger?: Logger;
debug?: boolean;
};
`
#### Values and defaults ( UI )
| Key | Type | Values | Default | Notes |
| --------------------------------------------------- | ------------------------------ | -------------------- | ----------------------------- | ----------------------------------------------------------------------------------------- |
| ui.statusMode | "block" \| "inline" \| "off" | block / inline / off | "block" | _block_ uses
, _inline_ overlays inside the input , _off_ hides UI |
| ui.statusIcon | "none" \| "icon" \| "pill" | none / icon / pill | "none" | used only when statusMode is inline |
| ui.showStatusText | boolean | true / false | blockโtrue , inlineโfalse | short text in inline ; full text in block |
| ui.iconPosition | "right" \| "left" | right / left | "right" | icon position for inline |
| ui.status | HTMLElement ( optional ) | โ | auto created / derived | existing host for status when you do not use wrapper |
| ui.button / dropdown / flagIcon / flagLabel | HTMLElement ( optional ) | โ | auto created if wrapper | for re-using external DOM |---
$3
`ts
type EuroPlateInstance = {
setCountry(code: "AUTO" | string): void; // alias of setMode
setMode(m: "AUTO" | string): void; // set fixed country or AUTO
setAllowed(codes: string[]): void; // dynamic whitelist
setVehicleType(t: "any" | "car" | "bike"): void;
setI18n(code: "AUTO" | "IT" | "EN"): void;
setDebug(on: boolean): void; validate(): { ok: boolean; country?: string; value: string };
destroy(): void;
getI18n(): "it" | "en";
};
`---
๐ผ๏ธ Usage examples
$3
`html
`> Notes :
>
> - With
autoLoadDeps.jquery: true and autoLoadDeps.toastr: true the client will fetch UMD builds from CDN when missing .
> - useToastrLogger: true sends SDK logs and validation notices to Toastr if it is present ( either auto-loaded or injected ) .
> - jQuery is not required by the core validator ; it is only pulled if your page / widgets rely on it .---
$3
`html
`---
$3
`html
`---
$3
`js
createEuroPlate(EuroMod, {
wrapper: "#plateBox",
cdn: { inputmask: "https://unpkg.com/inputmask@5.0.9/dist/inputmask.min.js" },
});
`---
$3
`js
createEuroPlate(EuroMod, {
wrapper: "#plateBox",
autoLoadDeps: { inputmask: false },
});
`---
$3
`html
`---
๐งฉ WordPress ( WP ) / Elementor
$3
`php
add_action('wp_enqueue_scripts', function () {
wp_register_script('epv-init', '', [], null, true); wp_enqueue_style(
'epv-styles',
'https://cdn.jsdelivr.net/npm/@codecorn/euro-plate-validator@1.0.14/dist/assets/css/styles.css',
[],
'1.0.14'
);
add_filter('script_loader_tag', function ($tag, $handle) {
if ($handle === 'epv-init') {
return '';
}
return $tag;
}, 10, 2);
wp_enqueue_script('epv-init');
});
`---
โ๏ธ WordPress / Elementor integration
You can enqueue the CSS and auto-inject a
window.__epvInit bootstrapper.Then, create a shortcode to instantiate it dynamically inside Elementor.
Full example available in the Italian README โ _โWordPress (WP) / Elementorโ_ section.
---
๐งช CLI Tool
`bash
npx @codecorn/euro-plate-validator "AB 123 CD" --countries IT,FR,DE --type car --pretty
`Options:
-
--countries / -c โ comma-separated list of country codes
- --type / -t โ car, motorcycle, or any
- --pretty / -p โ human-readable outputExit codes:
-
0 โ valid
- 1 โ invalid
- 2 โ bad arguments---
๐ Supported Countries
๐ฎ๐น IT | ๐ฌ๐ง UK | ๐ฉ๐ช DE | ๐ซ๐ท FR | ๐ช๐ธ ES | ๐ต๐น PT | ๐ณ๐ฑ NL | ๐ง๐ช BE | ๐จ๐ญ CH | ๐ฆ๐น AT | ๐ฎ๐ช IE | ๐ฑ๐บ LU ๐ฉ๐ฐ DK | ๐ธ๐ช SE | ๐ณ๐ด NO | ๐ซ๐ฎ FI | ๐ต๐ฑ PL | ๐จ๐ฟ CZ | ๐ธ๐ฐ SK | ๐ญ๐บ HU | ๐ท๐ด RO | ๐ง๐ฌ BG | ๐ธ๐ฎ SI | ๐ญ๐ท HR | ๐ฌ๐ท GR ๐ฑ๐น LT | ๐ฑ๐ป LV | ๐ช๐ช EE | ๐บ๐ฆ UA
---
๐งพ Changelog (highlights)
$3
- Inputmask
- Safe merge of
definitions (no hard override of defaults).
- New L token (letter) accepts lowercase and forces UPPERCASE (casing: "upper").
- Avoid redefining A/9; use H (IT) / C (ES) only when needed.
- applyMaskNow applied immediately on country change (no debounce race).
- Finalized placeholders via finalizeInputMaskLayouts + scripts/test-placeholders.mjs.- Client SDK
- Centralized logging (
imLog, imPreLog, imMounted, imError) using BADGE/LOG when debug: true.
- Lowercase input supported across layouts with L token.
- Examples updated with autoLoadDeps: { inputmask: true, jquery: true, toastr: true } and useToastrLogger: true.- Docs
- CDN bumped to 1.0.14.
- Notes about lowercase acceptance and uppercase coercion.
- Guidance to not override
A/9 and define only custom tokens for restricted alphabets.---
$3
- Status inline configurabile
-
statusMode: "inline" | "block" | "off"
- statusIcon: "none" | "icon" | "pill"
- showStatusText: boolean
- iconPosition: "left" | "right"- Riserva spazio automatica via
:has([data-state])
- Nessuno stato su campo vuoto / parziale
- Fix cambio paese (ITโFR) e Inputmask merge (A/H/9)
- Refactor UI status (setValidityUI unico writer)
- Add clearStatusUI() per idle neutro---
$3
- NEW โ
autoFocusOnInit (default: false) โ prevents autofocus on init.
- NEW โ preserveInputAttrs โ keeps external input id/name intact.
- UX โ renamed CSS classes from .iti__ โ .epv__.
- Dependencies โ auto-loads Inputmask` UMD via CDN; supports manual injection and CDN override.---
- CSS/Assets consolidation.
- Added Client SDK + autoload fallback.
- Updated README, docs, and npm package.
---
MIT ยฉ CodeCornโข โ see LICENSE
---
Federico Girolami Full-Stack Developer โข System Integrator โข Digital Solution Architect ๐ ๐ codecorn.it ๐ง f.girolami@codecorn.it ๐ github.com/fgirolami29
---
Pull requests are welcome. For major changes, please open an issue first.
> Powered by CodeCornโข ๐
---