Skip to content

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

Add your overrides to your Filament panel's theme CSS file. If you haven't created one yet:

bash
php artisan make:filament-theme

Then register it in your panel provider:

php
->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:

css
/* ✅ 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-*

ClassDescription
.fi-fo-address-previewMain wrapper
.fi-fo-address-preview-emptyEmpty/no-country state message
.fi-fo-address-preview-errorError state message
.fi-fo-address-preview-containerFlex container holding both cards
.fi-fo-address-preview-cardIndividual envelope card (both)
.fi-fo-address-preview-internationalInternational format card
.fi-fo-address-preview-domesticDomestic format card
.fi-fo-address-preview-badgeBadge label (both)
.fi-fo-address-preview-badge-internationalInternational badge
.fi-fo-address-preview-badge-domesticDomestic badge
.fi-fo-address-preview-contentAddress text block

Example:

css
.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)

ClassDescription
.fi-fo-address-search-fieldOuter wrapper for the entire search field section
.fi-fo-address-map-containerMap image container (the box holding the static map)

Example:

css
.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-*

ClassDescription
.vc-outerOuter amber-bordered container
.vc-headerHeader row (icon + text)
.vc-header-iconWarning icon wrapper
.vc-header-icon svgWarning icon SVG
.vc-header-textTitle and subtitle wrapper
.vc-header-title"Address Standardized by …" heading
.vc-header-bodySubtitle text
.vc-comparison-gridTwo-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-listField list inside either card
.vc-original-labelField label (uppercase, gray) in original card
.vc-original-valueField value (unchanged) in original card
.vc-original-value-changedField 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-labelField label in verified card
.vc-verified-valueField value (unchanged) in verified card
.vc-verified-value-changedField value (changed - bold green) in verified card
.vc-changes-bar"Changes detected: …" summary bar
.verification-actionsButton row
.vc-keep-btn"Keep My Version" button wrapper
.vc-use-btn"Use Standardized" button wrapper

Example:

css
/* 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.

ClassDescription
.fi-geocoding-toastOuter notification box
.fi-geocoding-spinnerSpinning SVG icon
.fi-geocoding-toast-title"Verifying address…" text

Example:

css
.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-*

ClassDescription
.fi-widget-usps-rate-limitMain widget wrapper
.fi-widget-usps-rate-limit-headerHeader row with status icon and title
.fi-widget-usps-rate-limit-header-iconStatus icon badge (colored by status)
.fi-widget-usps-rate-limit-titleMain title text
.fi-widget-usps-rate-limit-statusStatus message ("Healthy", "Warning", etc.)
.fi-widget-usps-rate-limit-resetReset countdown section
.fi-widget-usps-rate-limit-statsStats cards container
.fi-widget-usps-rate-limit-stat-cardIndividual stat card
.fi-widget-usps-rate-limit-stat-iconStat card icon badge
.fi-widget-usps-rate-limit-stat-labelStat card label
.fi-widget-usps-rate-limit-stat-valueStat card numeric value
.fi-widget-usps-rate-limit-progress-barProgress bar track
.fi-widget-usps-rate-limit-progress-fillProgress bar fill (colored by status)
.fi-widget-usps-rate-limit-alertWarning/critical alert section
.fi-widget-usps-rate-limit-footerFooter info row

Data attributes drive status-based colors:

AttributeThreshold
[data-status="healthy"]< 60% usage
[data-status="moderate"]60~79% usage
[data-status="warning"]80~89% usage
[data-status="critical"]≥ 90% usage

Example:

css
/* 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.

ClassLocation
.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:

css
.fi-bg-color-400 { --bg: var(--color-400) }

The button's own CSS rule reads it:

css
.fi-btn { background-color: var(--bg); }

So to reliably pin a button's color, override --bg (not background-color):

css
.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:

VariableDescription
--bgBackground (normal state)
--hover-bgBackground on hover
--dark-bgBackground in dark mode
--dark-hover-bgBackground on hover in dark mode
--textText and icon color
--hover-textText/icon color on hover
--dark-textText/icon color in dark mode
--dark-hover-textText/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

bash
php artisan vendor:publish --tag=filament-address-config

This creates config/addresses.php in your application.

Address Preview Labels

php
'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:

env
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.

php
// 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

css
.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

css
: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

css
.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)

php
// 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.

bash
php artisan vendor:publish --tag=filament-address-views

This copies views to resources/views/vendor/filament-address/. Always prefer CSS hooks and configuration over publishing views.


Tips

  1. Use browser DevTools to inspect elements and discover all available CSS hook classes before writing CSS.
  2. Test in both modes, and always verify changes in light and dark mode. Remember to use html.dark .your-class (not @media).
  3. Prefer CSS hooks over publishing views, since hooks survive package updates; published views don't.
  4. Button colors need CSS variable overrides; use --bg, --text etc. 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.

Released under a commercial license.