Customization Guide
Last updated: 2026-05-13
This guide shows you how to customize the appearance of Filament Address Pro using CSS hooks - no need to publish views.
Table of Contents
- How to Add Custom CSS
- Dark Mode
- CSS Hook Reference
- Configuration Options
- Common Recipes
- Publishing Views (Advanced)
How to Add Custom CSS
Add your overrides to your Filament panel's theme CSS file. If you haven't created one yet:
php artisan make:filament-themeThen register it in your panel provider:
->viteTheme('resources/css/filament/admin/theme.css')Or add it to an existing CSS file that's already loaded by your panel. CSS hooks use low specificity so your rules only need to match the class - no !important needed, except for button overrides.
Dark Mode
Important: Filament uses class-based dark mode, not the system media query. Always use html.dark .your-class for dark mode overrides:
/* ✅ Correct */
html.dark .fi-fo-address-preview-card {
background-color: rgb(17 24 39);
}
/* ❌ Wrong - has no effect in Filament */
@media (prefers-color-scheme: dark) {
.fi-fo-address-preview-card { ... }
}CSS Hook Reference
Address Preview Component
Displays international and domestic address formats in envelope-style cards.
Hook prefix: fi-fo-address-preview-*
| Class | Description |
|---|---|
.fi-fo-address-preview | Main wrapper |
.fi-fo-address-preview-empty | Empty/no-country state message |
.fi-fo-address-preview-error | Error state message |
.fi-fo-address-preview-container | Flex container holding both cards |
.fi-fo-address-preview-card | Individual envelope card (both) |
.fi-fo-address-preview-international | International format card |
.fi-fo-address-preview-domestic | Domestic format card |
.fi-fo-address-preview-badge | Badge label (both) |
.fi-fo-address-preview-badge-international | International badge |
.fi-fo-address-preview-badge-domestic | Domestic badge |
.fi-fo-address-preview-content | Address text block |
Example:
.fi-fo-address-preview-card {
border-radius: 16px;
box-shadow: 0 4px 6px rgb(0 0 0 / 0.1);
}
.fi-fo-address-preview-badge-international {
background: linear-gradient(135deg, #667eea, #764ba2);
}
html.dark .fi-fo-address-preview-card {
background-color: rgb(17 24 39);
border-color: rgb(75 85 99);
}Address Search Field Component
Displays the Google Places autocomplete input and static map preview.
Hook prefix: fi-fo-address-search-* (outer wrapper); fi-fo-address-map-* (map image internals)
| Class | Description |
|---|---|
.fi-fo-address-search-field | Outer wrapper for the entire search field section |
.fi-fo-address-map-container | Map image container (the box holding the static map) |
Example:
.fi-fo-address-search-field {
border-radius: 12px;
overflow: hidden;
}
.fi-fo-address-map-container {
border-radius: 8px;
border: 2px solid rgb(99 102 241);
}
html.dark .fi-fo-address-map-container {
border-color: rgb(129 140 248);
}Verification Comparison Dialog
The amber dialog shown when a verified address differs from the user's input. All visual properties are CSS-only (no inline styles), so every element is cleanly overridable.
Hook prefix: vc-*
| Class | Description |
|---|---|
.vc-outer | Outer amber-bordered container |
.vc-header | Header row (icon + text) |
.vc-header-icon | Warning icon wrapper |
.vc-header-icon svg | Warning icon SVG |
.vc-header-text | Title and subtitle wrapper |
.vc-header-title | "Address Standardized by …" heading |
.vc-header-body | Subtitle text |
.vc-comparison-grid | Two-column grid containing both cards |
.vc-original-card | "Your Input" card |
.vc-original-badge | "Original" badge label |
.vc-original-title | "Your Input" heading |
.vc-fields-list | Field list inside either card |
.vc-original-label | Field label (uppercase, gray) in original card |
.vc-original-value | Field value (unchanged) in original card |
.vc-original-value-changed | Field value (changed - orange) in original card |
.vc-verified-card | "Standardized Version" card |
.vc-verified-badge | "Recommended" badge label |
.vc-verified-title | "Standardized Version" heading |
.vc-verified-label | Field label in verified card |
.vc-verified-value | Field value (unchanged) in verified card |
.vc-verified-value-changed | Field value (changed - bold green) in verified card |
.vc-changes-bar | "Changes detected: …" summary bar |
.verification-actions | Button row |
.vc-keep-btn | "Keep My Version" button wrapper |
.vc-use-btn | "Use Standardized" button wrapper |
Example:
/* Change the outer border/background from amber to blue */
.vc-outer {
border-color: rgb(99 102 241);
background-color: rgb(238 242 255);
box-shadow: 0 4px 14px -2px rgb(99 102 241 / 0.3);
}
html.dark .vc-outer {
background-color: rgb(15 20 50);
border-color: rgb(99 102 241);
}
.vc-header-title { color: rgb(49 46 129); }
html.dark .vc-header-title { color: rgb(199 210 254); }
/* Override the "Use Standardized" button color */
.vc-use-btn button {
background-color: rgb(99 102 241) !important;
}
.vc-use-btn button:hover {
background-color: rgb(129 140 248) !important;
}Note: The vc-keep-btn and vc-use-btn button overrides require !important because Filament's button CSS variable system has higher specificity. See Admin Page Buttons for the full technique.
Geocoding Toast
The small spinner notification shown during auto-geocoding on field blur.
| Class | Description |
|---|---|
.fi-geocoding-toast | Outer notification box |
.fi-geocoding-spinner | Spinning SVG icon |
.fi-geocoding-toast-title | "Verifying address…" text |
Example:
.fi-geocoding-toast {
border-radius: 12px;
box-shadow: 0 8px 24px rgb(0 0 0 / 0.15);
}
.fi-geocoding-toast-title {
font-size: 0.875rem;
font-weight: 600;
}
html.dark .fi-geocoding-toast {
background-color: rgb(30 41 59);
border-color: rgb(71 85 105);
}USPS Rate Limit Widget
The dashboard widget showing USPS API usage and rate limit status.
Hook prefix: fi-widget-usps-rate-limit-*
| Class | Description |
|---|---|
.fi-widget-usps-rate-limit | Main widget wrapper |
.fi-widget-usps-rate-limit-header | Header row with status icon and title |
.fi-widget-usps-rate-limit-header-icon | Status icon badge (colored by status) |
.fi-widget-usps-rate-limit-title | Main title text |
.fi-widget-usps-rate-limit-status | Status message ("Healthy", "Warning", etc.) |
.fi-widget-usps-rate-limit-reset | Reset countdown section |
.fi-widget-usps-rate-limit-stats | Stats cards container |
.fi-widget-usps-rate-limit-stat-card | Individual stat card |
.fi-widget-usps-rate-limit-stat-icon | Stat card icon badge |
.fi-widget-usps-rate-limit-stat-label | Stat card label |
.fi-widget-usps-rate-limit-stat-value | Stat card numeric value |
.fi-widget-usps-rate-limit-progress-bar | Progress bar track |
.fi-widget-usps-rate-limit-progress-fill | Progress bar fill (colored by status) |
.fi-widget-usps-rate-limit-alert | Warning/critical alert section |
.fi-widget-usps-rate-limit-footer | Footer info row |
Data attributes drive status-based colors:
| Attribute | Threshold |
|---|---|
[data-status="healthy"] | < 60% usage |
[data-status="moderate"] | 60~79% usage |
[data-status="warning"] | 80~89% usage |
[data-status="critical"] | ≥ 90% usage |
Example:
/* Round out the stat cards */
.fi-widget-usps-rate-limit-stat-card {
border-radius: 16px;
box-shadow: 0 4px 6px rgb(0 0 0 / 0.08);
}
/* Custom critical state header color */
.fi-widget-usps-rate-limit-header[data-status="critical"] .fi-widget-usps-rate-limit-header-icon {
background: linear-gradient(135deg, #dc2626, #991b1b);
}
html.dark .fi-widget-usps-rate-limit-stat-card {
background-color: rgb(15 23 42);
border-color: rgb(51 65 85);
}Admin Page Buttons
Custom hook classes on action buttons in admin pages. Because Filament uses CSS variables for button colors, you must override the CSS variables (not background-color directly) and use !important.
| Class | Location |
|---|---|
.fi-btn-clean-expired | "Clean Expired" on Address Cache listing |
.fi-btn-import-addresses | "Import Addresses" on Addresses listing |
How Filament button colors work:
Filament generates classes like fi-bg-color-400 on the button element, where each class sets a CSS variable:
.fi-bg-color-400 { --bg: var(--color-400) }The button's own CSS rule reads it:
.fi-btn { background-color: var(--bg); }So to reliably pin a button's color, override --bg (not background-color):
.fi-btn-clean-expired {
--bg: rgb(245 158 11) !important; /* amber-500 */
--hover-bg: rgb(251 191 36) !important; /* amber-400 */
--dark-bg: rgb(245 158 11) !important;
--dark-hover-bg: rgb(251 191 36) !important;
--text: white !important;
--hover-text: white !important;
--dark-text: white !important;
--dark-hover-text: white !important;
}Available CSS variables:
| Variable | Description |
|---|---|
--bg | Background (normal state) |
--hover-bg | Background on hover |
--dark-bg | Background in dark mode |
--dark-hover-bg | Background on hover in dark mode |
--text | Text and icon color |
--hover-text | Text/icon color on hover |
--dark-text | Text/icon color in dark mode |
--dark-hover-text | Text/icon color on hover in dark mode |
Note: For named Filament colors (e.g. color="success"), you can also use var(--color-500) etc. to reference the panel's color palette. For fixed RGB values like the amber button above, use literal RGB values.
Configuration Options
Customize behavior via the configuration file.
Publishing Configuration
php artisan vendor:publish --tag=filament-address-configThis creates config/addresses.php in your application.
Address Preview Labels
'ui' => [
'preview' => [
'international_label' => 'FOR INTERNATIONAL MAIL',
'domestic_label' => 'FOR DOMESTIC MAIL',
'empty_message' => 'Please enter address information',
'no_country_message' => 'Please select a country first',
],
],Or via environment variables:
ADDRESS_PREVIEW_INTERNATIONAL_LABEL="INTERNATIONAL"
ADDRESS_PREVIEW_DOMESTIC_LABEL="DOMESTIC"
ADDRESS_PREVIEW_EMPTY_MESSAGE="Fill in address fields to see preview"
ADDRESS_PREVIEW_NO_COUNTRY_MESSAGE="Select a country to see address preview"Quality Score Weights and Thresholds
The point values used to calculate quality scores (0–100) and the thresholds that define each quality level are configurable via environment variables or the published config.
// config/addresses.php
'quality_score' => [
'weights' => [
'completeness' => [
'required_fields' => 15, // country + address_line_1 + postal_code
'optional_fields' => 10, // locality, administrative_area, or address_line_2
'has_coordinates' => 5, // lat/lon captured
'structured_subdivisions'=> 5, // subdivision IDs, not just text
],
'verification' => [
'verified_confirmed' => 40, // full delivery point confirmed (USPS/Smarty DPV=Y)
'verified_warnings' => 25, // delivery point caveats (USPS/Smarty DPV=D/S)
'verified_needs_review' => 15, // verified but flagged for review
'verified_basic' => 20, // verified, no granular delivery point data (Google, Loqate)
],
'data_quality' => [
'no_duplicate' => 10,
'has_additional_fields' => 5, // bldg, box, or ico populated
],
'recency' => [
'within_30_days' => 10,
'within_90_days' => 5,
],
],
'thresholds' => [
'excellent' => 80,
'good' => 60,
'fair' => 40,
'poor' => 20, // scores below this are "Very Poor"
],
],All values can also be set via environment variables - see the Quick Reference table in docs/CONFIGURATION-GUIDE.md for the full list of ADDRESS_QUALITY_* variables.
Common Recipes
Recipe 1: Minimal Clean Design
.fi-fo-address-preview-card {
border-width: 1px;
border-radius: 12px;
box-shadow: none;
}
.fi-fo-address-preview-badge-international,
.fi-fo-address-preview-badge-domestic {
background: rgb(107 114 128);
font-size: 0.7rem;
}Recipe 2: Brand Colors Throughout
:root {
--my-primary: #6366f1;
--my-primary-light: #818cf8;
}
/* Address preview cards */
.fi-fo-address-preview-badge-international { background: var(--my-primary); }
.fi-fo-address-preview-badge-domestic { background: var(--my-primary); }
.fi-fo-address-preview-card { border-color: var(--my-primary); }
/* Address search field border */
.fi-fo-address-map-container { border: 2px solid var(--my-primary); }
/* Verification dialog - amber replaced with brand color */
.vc-outer {
border-color: var(--my-primary);
background-color: rgb(238 242 255);
box-shadow: 0 4px 14px -2px color-mix(in srgb, var(--my-primary) 30%, transparent);
}
/* Import button */
.fi-btn-import-addresses {
--bg: var(--my-primary) !important;
--hover-bg: var(--my-primary-light) !important;
--dark-bg: var(--my-primary) !important;
--dark-hover-bg: var(--my-primary-light) !important;
--text: white !important;
--hover-text: white !important;
--dark-text: white !important;
--dark-hover-text: white !important;
}Recipe 3: Compact Preview Cards
.fi-fo-address-preview-card {
padding: 1rem;
min-width: 200px;
}
.fi-fo-address-preview-content {
margin-top: 1.5rem;
font-size: 0.85rem;
line-height: 1.5;
}
.fi-fo-address-preview-badge {
font-size: 0.65rem;
}Recipe 4: Localized Labels (Spanish Example)
// config/addresses.php
'ui' => [
'preview' => [
'international_label' => 'CORREO INTERNACIONAL',
'domestic_label' => 'CORREO NACIONAL',
'empty_message' => 'Rellene los campos de dirección para ver la vista previa',
'no_country_message' => 'Seleccione un país para ver la vista previa',
],
],Publishing Views (Advanced)
For extreme customization, you can publish the Blade views. This is not recommended, since published views can't automatically receive bug fixes or feature updates.
php artisan vendor:publish --tag=filament-address-viewsThis copies views to resources/views/vendor/filament-address/. Always prefer CSS hooks and configuration over publishing views.
Tips
- Use browser DevTools to inspect elements and discover all available CSS hook classes before writing CSS.
- Test in both modes, and always verify changes in light and dark mode. Remember to use
html.dark .your-class(not@media). - Prefer CSS hooks over publishing views, since hooks survive package updates; published views don't.
- Button colors need CSS variable overrides; use
--bg,--textetc. with!important(see Admin Page Buttons).
Version Compatibility
CSS hooks are stable across minor and patch releases. Breaking changes to hook names only occur in major version updates.