Package Exports
- @codecorn/euro-plate-validator
- @codecorn/euro-plate-validator/browser
- @codecorn/euro-plate-validator/client
- @codecorn/euro-plate-validator/package.json
Readme
๐ @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).
โจ Features
- โ 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
Inputmaskintegration - โ๏ธ 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
๐ฆ Installation
npm install @codecorn/euro-plate-validator๐ CDN (v1.0.14)
Use versioned URLs to avoid stale CDN caches.
Core module
ESM (browser)
https://cdn.jsdelivr.net/npm/@codecorn/euro-plate-validator@1.0.14/dist/browser/index.esm.jsIIFE (global
window.EuroPlateValidator)https://cdn.jsdelivr.net/npm/@codecorn/euro-plate-validator@1.0.14/dist/browser/index.iife.min.js
Client SDK (UI)
ESM
https://cdn.jsdelivr.net/npm/@codecorn/euro-plate-validator@1.0.14/dist/client/index.mjsCJS (Node)
https://cdn.jsdelivr.net/npm/@codecorn/euro-plate-validator@1.0.14/dist/client/europlate.client.cjs
Assets (CSS)
https://cdn.jsdelivr.net/npm/@codecorn/euro-plate-validator@1.0.14/dist/assets/css/styles.css- (compat alias)
โฆ/assets/css/styles.css
๐ง Core API
Node.js / TypeScript
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"]);๐งฉ Browser Client SDK โ createEuroPlate()
The browser client auto-generates a full UI (flag + input + dropdown + status) or attaches to an existing <input>. 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 .
๐ง Core API ( Node / 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"]);๐งฉ Client SDK ( UI ) โ createEuroPlate
The client either generates the markup ( flag + input + country dropdown + status ) or attaches to an existing input .
Main options ( including new ones )
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 <div class="status"> under the input ( back-compat , default )
* - "inline" โ overlays inside the input , does not change height
* - "off" โ hides status text / icon
*/
statusMode?: "block" | "inline" | "off"; // default: "block"
/** 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<string, (s: string) => string>; // per country code
// 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 <div class="status"> , 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 |
Instance methods
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
A ) Quick start with a shared common config + autoload deps ( Inputmask , jQuery , Toastr )
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@codecorn/euro-plate-validator@1.0.14/dist/assets/css/styles.css" />
<div id="plateBox"></div>
<script type="module">
import * as EuroMod from "https://cdn.jsdelivr.net/npm/@codecorn/euro-plate-validator@1.0.14/dist/browser/index.esm.js";
import { createEuroPlate } from "https://cdn.jsdelivr.net/npm/@codecorn/euro-plate-validator@1.0.14/dist/client/index.mjs";
// Common options used across examples
const common = {
mode: "AUTO",
i18n: "IT",
allowedCountries: ["IT", "FR", "DE", "ES"],
vehicleType: "any",
autoFocusOnInit: false,
ui: {
statusMode: "inline",
statusIcon: "icon",
showStatusText: true, // | false
iconPosition: "right",
},
// Autoload deps (UMD) from CDN
autoLoadDeps: { inputmask: true, jquery: true, toastr: true },
// Optional : route logs to Toastr if available
useToastrLogger: true,
debug: true,
};
createEuroPlate(EuroMod, {
wrapper: "#plateBox", // optional
...common,
});
</script>Notes :
- With
autoLoadDeps.jquery: trueandautoLoadDeps.toastr: truethe client will fetch UMD builds from CDN when missing .useToastrLogger: truesends 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 .
B ) You provide Inputmask manually ( UMD โ window.Inputmask )
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@codecorn/euro-plate-validator@1.0.14/dist/assets/css/styles.css" />
<script src="https://cdn.jsdelivr.net/npm/inputmask@5.0.9/dist/inputmask.min.js"></script>
<script type="module">
import * as EuroMod from "https://cdn.jsdelivr.net/npm/@codecorn/euro-plate-validator@1.0.14/dist/browser/index.esm.js";
import { createEuroPlate } from "https://cdn.jsdelivr.net/npm/@codecorn/euro-plate-validator@1.0.14/dist/client/index.mjs";
createEuroPlate(EuroMod, {
wrapper: "#plateBox",
i18n: "AUTO",
autoFocusOnInit: false,
deps: { inputmask: window.Inputmask }, // manual inject
});
</script>C ) Autoload deps from CDN ( default , Inputmask only )
<script type="module">
import * as EuroMod from "https://cdn.jsdelivr.net/npm/@codecorn/euro-plate-validator@1.0.14/dist/browser/index.esm.js";
import { createEuroPlate } from "https://cdn.jsdelivr.net/npm/@codecorn/euro-plate-validator@1.0.14/dist/client/index.mjs";
createEuroPlate(EuroMod, {
wrapper: "#plateBox",
i18n: "AUTO",
autoFocusOnInit: false,
// No deps object โ will autoload Inputmask UMD from jsDelivr
});
</script>D ) Autoload ON with a custom CDN URL
createEuroPlate(EuroMod, {
wrapper: "#plateBox",
cdn: { inputmask: "https://unpkg.com/inputmask@5.0.9/dist/inputmask.min.js" },
});E ) Disable autoload ( โno maskโ fallback , no error )
createEuroPlate(EuroMod, {
wrapper: "#plateBox",
autoLoadDeps: { inputmask: false },
});F ) Attach to an existing input ( no auto-build )
<input id="myPlate" />
<script type="module">
import * as EuroMod from ".../index.esm.js";
import { createEuroPlate } from ".../index.mjs";
createEuroPlate(EuroMod, {
input: document.getElementById("myPlate"),
inputName: "plate_number",
preserveInputAttrs: true, // do NOT overwrite existing id/name
i18n: "EN",
mode: "AUTO",
autoFocusOnInit: false,
});
</script>๐งฉ WordPress ( WP ) / Elementor
1 ) Enqueue CSS + init helper ( type = "module" )
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 '<script type="module">' .
'import * as EuroMod from "https://cdn.jsdelivr.net/npm/@codecorn/euro-plate-validator@1.0.14/dist/browser/index.esm.js";' .
'import { createEuroPlate } from "https://cdn.jsdelivr.net/npm/@codecorn/euro-plate-validator@1.0.14/dist/client/index.mjs";' .
'window.__epvInit=(id,opts)=>createEuroPlate(EuroMod,Object.assign({wrapper:"#"+id,mode:"AUTO",i18n:"IT",debug:true,autoFocusOnInit:false},opts||{}));' .
'</script>';
}
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
npx @codecorn/euro-plate-validator "AB 123 CD" --countries IT,FR,DE --type car --prettyOptions:
--countries/-cโ comma-separated list of country codes--type/-tโcar,motorcycle, orany--pretty/-pโ human-readable output
Exit codes:
0โ valid1โ invalid2โ 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)
1.0.14
Inputmask
- Safe merge of
definitions(no hard override of defaults). - New
Ltoken (letter) accepts lowercase and forces UPPERCASE (casing: "upper"). - Avoid redefining
A/9; useH(IT) /C(ES) only when needed. applyMaskNowapplied immediately on country change (no debounce race).- Finalized placeholders via
finalizeInputMaskLayouts+scripts/test-placeholders.mjs.
- Safe merge of
Client SDK
- Centralized logging (
imLog,imPreLog,imMounted,imError) usingBADGE/LOGwhendebug: true. - Lowercase input supported across layouts with
Ltoken. - Examples updated with
autoLoadDeps: { inputmask: true, jquery: true, toastr: true }anduseToastrLogger: true.
- Centralized logging (
Docs
- CDN bumped to 1.0.14.
- Notes about lowercase acceptance and uppercase coercion.
- Guidance to not override
A/9and define only custom tokens for restricted alphabets.
1.0.13
Status inline configurabile
statusMode: "inline" | "block" | "off"statusIcon: "none" | "icon" | "pill"showStatusText: booleaniconPosition: "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 (
setValidityUIunico writer)Add
clearStatusUI()per idle neutro
1.0.12
- NEW โ
autoFocusOnInit(default:false) โ prevents autofocus on init. - NEW โ
preserveInputAttrsโ keeps external inputid/nameintact. - UX โ renamed CSS classes from
.iti__*โ.epv__*. - Dependencies โ auto-loads
InputmaskUMD via CDN; supports manual injection and CDN override. - I18n โ IT / EN / AUTO (auto-detect from browser locale).
- UX stability โ dynamic placeholder, country-based formatter, debounce system.
1.0.10โ11
- CSS/Assets consolidation.
- Added Client SDK + autoload fallback.
- Updated README, docs, and npm package.
๐ License
MIT ยฉ CodeCornโข โ see LICENSE
๐ค Maintainer
Federico Girolami Full-Stack Developer โข System Integrator โข Digital Solution Architect ๐ ๐ codecorn.it ๐ง f.girolami@codecorn.it ๐ github.com/fgirolami29
๐ค Contributing
Pull requests are welcome. For major changes, please open an issue first.
Powered by CodeCornโข ๐