Address Validation Demo

Try Address Validation

Use this demo to try the Address Validation API using any address from a supported region. The demo takes address components as input, and displays the validation response below. To parse an unstructured address, enter the entire address in the Street Address 1 field. Select example addresses from the drop-down at the top of the form.

TypeScript

// --- DOM Refs ---
const addressForm = document.getElementById('address-form');
const validateButton = document.getElementById('validate-button');
const clearFormButton = document.getElementById('clear-form-button');
const resultDisplay = document.getElementById('result-display');
const loadingText = document.getElementById('loading-text');
// --- Input field refs ---
const streetAddress1Input = document.getElementById('street-address-1') as HTMLInputElement;
const streetAddress2Input = document.getElementById('street-address-2') as HTMLInputElement;
const cityInput = document.getElementById('city') as HTMLInputElement;
const stateInput = document.getElementById('state') as HTMLInputElement;
const zipCodeInput = document.getElementById('zip-code') as HTMLInputElement;
const regionSelect = document.getElementById('region-select') as HTMLSelectElement;
const exampleSelect = document.getElementById('example-select') as HTMLSelectElement;

// --- Core Initialization ---
async function init() {
  // Load the Address Validation library
  await google.maps.importLibrary('addressValidation');
  // Set event listeners
  addressForm!.addEventListener('submit', handleValidationSubmit);
  exampleSelect!.addEventListener('change', handleExampleSelectChange);
  clearFormButton!.addEventListener('click', handleClearForm);
}

// --- Validation Handler ---
async function handleValidationSubmit(event) {
  event.preventDefault();  // Prevent default form submission
  resultDisplay!.textContent = 'Validating...';  // Clear previous results

  // Validate the address
  try {
    //@ts-ignore
    const result = await google.maps.addressValidation.AddressValidation.fetchAddressValidation({
      address: {
        regionCode: regionSelect!.value.trim(),
        languageCode: 'en',
        addressLines: [
          streetAddress1Input!.value.trim(),
          streetAddress2Input!.value.trim()
        ].filter(line => line),  // Filter out empty lines
        locality: cityInput!.value.trim(),
        administrativeArea: stateInput!.value.trim(),
        postalCode: zipCodeInput!.value.trim(),
      },
    });

    resultDisplay!.textContent =
        "Verdict summary\n================\n" +
        `Formatted address: ${result.address.formattedAddress}\n` +
        `Entered: ${result.verdict.inputGranularity}\n` +
        `Validated: ${result.verdict.validationGranularity}\n` +
        `Geocoded: ${result.verdict.geocodeGranularity}\n\n` +
        `${getVerdictMessage(result.verdict, 'addressComplete')}\n` +
        `${getVerdictMessage(result.verdict, 'hasUnconfirmedComponents')}\n` +
        `${getVerdictMessage(result.verdict, 'hasInferredComponents')}\n` +
        `${getVerdictMessage(result.verdict, 'hasReplacedComponents')}\n\n` +
        `Raw JSON response\n=================\n` +
        JSON.stringify(result, null, '  ');

  } catch (error) {
    console.error('Validation failed:', error);    
    if (error instanceof Error) {
      resultDisplay!.textContent = `Error: ${error.message}`;
    }
  } 
}

// --- Verdict Messages ---
const verdictMessages = {
  addressComplete: {
    trueMessage:
        '- The API found no unresolved, unexpected, or missing address elements.',
    falseMessage:
        '- At least one address element is unresolved, unexpected, or missing.',
  },
  hasUnconfirmedComponents: {
    trueMessage: '- The API can\'t confirm at least one address component.',
    falseMessage: '- The API confirmed all address components.',
  },
  hasInferredComponents: {
    trueMessage: '- The API inferred (added) at least one address component.',
    falseMessage: '- The API did not infer (add) any address components.',
  },
  hasReplacedComponents: {
    trueMessage: '- The API replaced at least one address component.',
    falseMessage: '- The API did not replace any address components.',
  },
};

// Helper function to get the verdict message for a given verdict key
function getVerdictMessage(verdict, key) {
  if (!verdict || !verdictMessages[key]) return 'Unknown';
  return verdict[key] ? verdictMessages[key].trueMessage :
                        verdictMessages[key].falseMessage;
}

// Handler for Dropdown Change
function handleExampleSelectChange(event) {
  const selectedValue = event.target.value; // e.g., "google", "suite", ""
  if (selectedValue && examples[selectedValue]) {
      populateAddressFields(examples[selectedValue]);
  } else if (!selectedValue) {
      // Optional: Clear fields if the "-- Select --" option is chosen
      populateAddressFields(null); // Pass null to clear fields
  }
}

// Clear Form Handler
function handleClearForm() {
  streetAddress1Input!.value = '';
  streetAddress2Input!.value = '';
  cityInput!.value = '';
  stateInput!.value = '';
  zipCodeInput!.value = '';
  regionSelect!.value = '';
  exampleSelect!.value = '';
  resultDisplay!.textContent = 'Result will appear here...';
  console.log('Cleared form');
}

// Example Address Data
const examples = {
  google: {
      streetAddress1: '1600 Amphitheatre Parkway',
      streetAddress2: '', // Explicitly empty
      city: 'Mountain View',
      state: 'CA',
      zipCode: '94043',
      region: 'US'
  },
  nonExistentSubpremise: {
      streetAddress1: '2930 Pearl St.',
      streetAddress2: 'Suite 100',
      city: 'Boulder',
      state: 'CO',
      zipCode: '', // Explicitly empty
      region: 'US'
  },
  missingSubpremise: {
      streetAddress1: '500 West 2nd Street',
      streetAddress2: null, // Can use null or undefined too
      city: 'Austin',
      state: 'TX',
      zipCode: '78701',
      region: 'US'
  },
  misspelledLocality: {
      streetAddress1: '1600 Amphitheatre Pkwy',
      streetAddress2: '',
      city: 'Montan View',
      state: 'CA',
      zipCode: '94043',
      region: 'US'
  },
  missingLocality: {
      streetAddress1: 'Brandschenkestrasse 110 8002',
      streetAddress2: '',
      city: '',
      state: '',
      zipCode: '',
      region: ''
  },
  usPoBox: {
      streetAddress1: 'PO Box 1108',
      streetAddress2: '',
      city: 'Sterling',
      state: 'VA',
      zipCode: '20166-1108',
      region: 'US'
  },
};

// Helper function to populate form fields with example address data
function populateAddressFields(exampleAddress) {
  if (!exampleAddress) {
      console.warn("No example address data provided.");
      return;
  }

  // Get values from example, providing empty string as default
  streetAddress1Input!.value = exampleAddress.streetAddress1 || '';
  streetAddress2Input!.value = exampleAddress.streetAddress2 || '';
  cityInput!.value = exampleAddress.city || '';
  stateInput!.value = exampleAddress.state || '';
  zipCodeInput!.value = exampleAddress.zipCode || '';
  regionSelect!.value = exampleAddress.region || '';

  // Clear previous results and errors
  resultDisplay!.textContent = 'Result will appear here...';

  console.log("Populated fields with example:", exampleAddress);
}

init();

JavaScript

// --- DOM Refs ---
const addressForm = document.getElementById('address-form');
const validateButton = document.getElementById('validate-button');
const clearFormButton = document.getElementById('clear-form-button');
const resultDisplay = document.getElementById('result-display');
const loadingText = document.getElementById('loading-text');
// --- Input field refs ---
const streetAddress1Input = document.getElementById('street-address-1');
const streetAddress2Input = document.getElementById('street-address-2');
const cityInput = document.getElementById('city');
const stateInput = document.getElementById('state');
const zipCodeInput = document.getElementById('zip-code');
const regionSelect = document.getElementById('region-select');
const exampleSelect = document.getElementById('example-select');
// --- Core Initialization ---
async function init() {
    // Load the Address Validation library
    await google.maps.importLibrary('addressValidation');
    // Set event listeners
    addressForm.addEventListener('submit', handleValidationSubmit);
    exampleSelect.addEventListener('change', handleExampleSelectChange);
    clearFormButton.addEventListener('click', handleClearForm);
}
// --- Validation Handler ---
async function handleValidationSubmit(event) {
    event.preventDefault(); // Prevent default form submission
    resultDisplay.textContent = 'Validating...'; // Clear previous results
    // Validate the address
    try {
        //@ts-ignore
        const result = await google.maps.addressValidation.AddressValidation.fetchAddressValidation({
            address: {
                regionCode: regionSelect.value.trim(),
                languageCode: 'en',
                addressLines: [
                    streetAddress1Input.value.trim(),
                    streetAddress2Input.value.trim()
                ].filter(line => line), // Filter out empty lines
                locality: cityInput.value.trim(),
                administrativeArea: stateInput.value.trim(),
                postalCode: zipCodeInput.value.trim(),
            },
        });
        resultDisplay.textContent =
            "Verdict summary\n================\n" +
                `Formatted address: ${result.address.formattedAddress}\n` +
                `Entered: ${result.verdict.inputGranularity}\n` +
                `Validated: ${result.verdict.validationGranularity}\n` +
                `Geocoded: ${result.verdict.geocodeGranularity}\n\n` +
                `${getVerdictMessage(result.verdict, 'addressComplete')}\n` +
                `${getVerdictMessage(result.verdict, 'hasUnconfirmedComponents')}\n` +
                `${getVerdictMessage(result.verdict, 'hasInferredComponents')}\n` +
                `${getVerdictMessage(result.verdict, 'hasReplacedComponents')}\n\n` +
                `Raw JSON response\n=================\n` +
                JSON.stringify(result, null, '  ');
    }
    catch (error) {
        console.error('Validation failed:', error);
        if (error instanceof Error) {
            resultDisplay.textContent = `Error: ${error.message}`;
        }
    }
}
// --- Verdict Messages ---
const verdictMessages = {
    addressComplete: {
        trueMessage: '- The API found no unresolved, unexpected, or missing address elements.',
        falseMessage: '- At least one address element is unresolved, unexpected, or missing.',
    },
    hasUnconfirmedComponents: {
        trueMessage: '- The API can\'t confirm at least one address component.',
        falseMessage: '- The API confirmed all address components.',
    },
    hasInferredComponents: {
        trueMessage: '- The API inferred (added) at least one address component.',
        falseMessage: '- The API did not infer (add) any address components.',
    },
    hasReplacedComponents: {
        trueMessage: '- The API replaced at least one address component.',
        falseMessage: '- The API did not replace any address components.',
    },
};
// Helper function to get the verdict message for a given verdict key
function getVerdictMessage(verdict, key) {
    if (!verdict || !verdictMessages[key])
        return 'Unknown';
    return verdict[key] ? verdictMessages[key].trueMessage :
        verdictMessages[key].falseMessage;
}
// Handler for Dropdown Change
function handleExampleSelectChange(event) {
    const selectedValue = event.target.value; // e.g., "google", "suite", ""
    if (selectedValue && examples[selectedValue]) {
        populateAddressFields(examples[selectedValue]);
    }
    else if (!selectedValue) {
        // Optional: Clear fields if the "-- Select --" option is chosen
        populateAddressFields(null); // Pass null to clear fields
    }
}
// Clear Form Handler
function handleClearForm() {
    streetAddress1Input.value = '';
    streetAddress2Input.value = '';
    cityInput.value = '';
    stateInput.value = '';
    zipCodeInput.value = '';
    regionSelect.value = '';
    exampleSelect.value = '';
    resultDisplay.textContent = 'Result will appear here...';
    console.log('Cleared form');
}
// Example Address Data
const examples = {
    google: {
        streetAddress1: '1600 Amphitheatre Parkway',
        streetAddress2: '', // Explicitly empty
        city: 'Mountain View',
        state: 'CA',
        zipCode: '94043',
        region: 'US'
    },
    nonExistentSubpremise: {
        streetAddress1: '2930 Pearl St.',
        streetAddress2: 'Suite 100',
        city: 'Boulder',
        state: 'CO',
        zipCode: '', // Explicitly empty
        region: 'US'
    },
    missingSubpremise: {
        streetAddress1: '500 West 2nd Street',
        streetAddress2: null, // Can use null or undefined too
        city: 'Austin',
        state: 'TX',
        zipCode: '78701',
        region: 'US'
    },
    misspelledLocality: {
        streetAddress1: '1600 Amphitheatre Pkwy',
        streetAddress2: '',
        city: 'Montan View',
        state: 'CA',
        zipCode: '94043',
        region: 'US'
    },
    missingLocality: {
        streetAddress1: 'Brandschenkestrasse 110 8002',
        streetAddress2: '',
        city: '',
        state: '',
        zipCode: '',
        region: ''
    },
    usPoBox: {
        streetAddress1: 'PO Box 1108',
        streetAddress2: '',
        city: 'Sterling',
        state: 'VA',
        zipCode: '20166-1108',
        region: 'US'
    },
};
// Helper function to populate form fields with example address data
function populateAddressFields(exampleAddress) {
    if (!exampleAddress) {
        console.warn("No example address data provided.");
        return;
    }
    // Get values from example, providing empty string as default
    streetAddress1Input.value = exampleAddress.streetAddress1 || '';
    streetAddress2Input.value = exampleAddress.streetAddress2 || '';
    cityInput.value = exampleAddress.city || '';
    stateInput.value = exampleAddress.state || '';
    zipCodeInput.value = exampleAddress.zipCode || '';
    regionSelect.value = exampleAddress.region || '';
    // Clear previous results and errors
    resultDisplay.textContent = 'Result will appear here...';
    console.log("Populated fields with example:", exampleAddress);
}
init();

CSS

body,
html {
    height: 100%;
    margin: 0;
    padding: 0;
    overflow: hidden;
    font-family: "Google Sans", sans-serif;
    font-size: 20px;
    color: #333;
    background-color: #f4f4f9
}

#sidebar {
    width: 800px;
    max-width: calc(100% - 2rem);
    background-color: #fff;
    border-radius: .5rem;
    box-shadow: 0 4px 6px -1px rgba(0, 0, 0, .1), 0 2px 4px -1px rgba(0, 0, 0, .06);
    display: flex;
    flex-direction: column;
    overflow: hidden;
    max-height: calc(100% - 2rem);
}

.sidebar-header {
    padding: .75rem;
    border-bottom: 1px solid #e5e7eb;
    flex-shrink: 0
}

.sidebar-header h2 {
    margin: 0;
    font-size: 1.125rem;
    font-weight: 600;
    color: #1f2937
}

.sidebar-content {
    padding: .75rem;
    overflow-y: auto;
    flex-grow: 1
}

.sidebar-content::-webkit-scrollbar {
    width: 6px
}

.sidebar-content::-webkit-scrollbar-thumb {
    background-color: rgba(0, 0, 0, .2);
    border-radius: 3px
}

#address-form>div {
    margin-bottom: .75rem
}

#address-form>button {
    margin-top: 1rem
}

label {
    display: block;
    font-size: .75rem;
    font-weight: 500;
    color: #4b5563;
    margin-bottom: .25rem
}

input[type=text] {
    width: 100%;
    padding: .5rem .75rem;
    font-size: .875rem;
    border: 1px solid #d1d5db;
    border-radius: .375rem;
    box-sizing: border-box;
    transition: border-color .15s ease-in-out, box-shadow .15s ease-in-out
}

input[type=text]:focus {
    outline: 0;
    border-color: #2563eb;
    box-shadow: 0 0 0 1px #2563eb
}

.form-grid-triple {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: .75rem
}

@media (max-width:400px) {
    .form-grid-triple {
        grid-template-columns: 1fr
    }
}

button {
    display: inline-block;
    margin-right: .5rem;
    width: auto;
    padding: .6rem .75rem;
    font-size: .875rem;
    font-weight: 500;
    color: #fff;
    background-color: #2563eb;
    border: none;
    border-radius: .375rem;
    cursor: pointer;
    transition: background-color .15s ease-in-out;
    text-align: center
}

button:hover {
    background-color: #1d4ed8
}

#loading-indicator {
    margin-top: .5rem;
    font-size: .75rem;
    color: #2563eb;
    font-style: italic;
    display: none;
    align-items: center;
    gap: .5rem
}

.spinner {
    width: 1em;
    height: 1em;
    border: 2px solid currentColor;
    border-right-color: transparent;
    border-radius: 50%;
    animation: spin 1s linear infinite;
    display: inline-block
}

@keyframes spin {
    to {
        transform: rotate(360deg)
    }
}

#error-message {
    margin-top: .5rem;
    font-size: .75rem;
    color: #dc2626;
    font-weight: 500;
    display: none
}

#result-container {
    margin-top: 1rem;
    border-top: 1px solid #e5e7eb;
    padding-top: .75rem
}

#result-display {
    font-family: Consolas, Monaco, "Andale Mono", "Ubuntu Mono", monospace;
    font-size: .75rem;
    background-color: #f3f4f6;
    padding: .5rem;
    border-radius: .25rem;
    overflow-x: auto;
    white-space: pre;
    height: 12rem;
    border: 1px solid #e5e7eb
}

@media (max-width:767px) {
    #sidebar {
        width: auto;
        max-width: 100%;
        margin: 0;
        max-height: 70vh;
        border-radius: 0;
        border-top-left-radius: .5rem;
        border-top-right-radius: .5rem;
        border-top: 1px solid #d1d5db;
        box-shadow: 0 -4px 6px -1px rgba(0, 0, 0, .1), 0 -2px 4px -1px rgba(0, 0, 0, .06)
    }
}

.form-select {
    display: block;
    width: 100%;
    padding: .5rem 2.5rem .5rem .75rem;
    font-size: .875rem;
    font-weight: 400;
    line-height: 1.5;
    color: #333;
    background-color: #fff;
    background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23343a40' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M2 5l6 6 6-6'/%3e%3c/svg%3e");
    background-repeat: no-repeat;
    background-position: right .75rem center;
    background-size: 16px 12px;
    border: 1px solid #d1d5db;
    border-radius: .375rem;
    appearance: none;
    transition: border-color .15s ease-in-out, box-shadow .15s ease-in-out;
    cursor: pointer
}

.form-select:focus {
    border-color: #2563eb;
    outline: 0;
    box-shadow: 0 0 0 1px #2563eb
}

.form-select option[disabled] {
    color: #9ca3af
}

HTML

<html>
  <head>
    <title>Address Validation</title>

    <link rel="stylesheet" type="text/css" href="./style.css" />
    <script type="module" src="./index.js"></script>
  </head>
  <body>
      <!-- Address Validation Form Container -->
      <div id="sidebar">
        <!-- Header -->
        <div class="sidebar-header">
          <h2>Address Validation</h2>
        </div>
        <!-- Content: Address Form -->
        <form id="address-form" class="sidebar-content" autocomplete="off">
          <!-- Example Dropdown Section -->
          <div id="example-dropdown-container" style="margin-bottom: 1rem; padding-bottom: 0.75rem; border-bottom: 1px solid #e5e7eb;">
            <label for="example-select" style="margin-bottom: 0.5rem;">Load Example Address:</label>
            <select id="example-select" name="exampleSelect" class="form-select">
              <option value="" selected disabled>-- Select an Example --</option>
              <option value="google">Valid Address</option>
              <option value="nonExistentSubpremise">Non-existent Subpremise</option>
              <option value="missingSubpremise">Missing Subpremise</option>
              <option value="misspelledLocality">Misspelled Locality</option>
              <option value="missingLocality">Missing Locality</option>
              <option value="usPoBox">US PO Box</option>
            </select>
          </div>
          <div>
            <label for="street-address-1">Street Address 1</label>
            <input
              id="street-address-1"
              name="streetAddress1"
              type="text"
              placeholder="e.g., 1600 Amphitheatre Parkway"
            />
          </div>
          <div>
            <label for="street-address-2">Street Address 2 (Optional)</label>
            <input
              id="street-address-2"
              name="streetAddress2"
              type="text"
              placeholder="e.g., Suite 100"
            />
          </div>
          <!-- Use a div with grid class for City/State/ZIP layout -->
          <div class="form-grid-triple">
            <div>
              <label for="city">City</label>
              <input id="city" name="city" type="text" placeholder="e.g., Mountain View" />
            </div>
            <div>
              <label for="state">State or territory</label>
              <input id="state" name="state" type="text" placeholder="e.g., CA" />
            </div>
            <div>
              <label for="zip-code">ZIP Code</label>
              <input id="zip-code" name="zipCode" type="text" placeholder="e.g., 94043" />
            </div>
          </div>
          <div id="region-select-container">
            <div>
              <label for="region-select">Region</label>
              <select id="region-select" name="regionSelect" class="form-select">
                <option value="AR">Argentina</option>
                <option value="AU">Australia</option>
                <option value="AT">Austria</option>
                <option value="BE">Belgium</option>
                <option value="BR">Brazil</option>
                <option value="BG">Bulgaria</option>
                <option value="CA">Canada</option>
                <option value="CL">Chile</option>
                <option value="CO">Colombia</option>
                <option value="HR">Croatia</option>
                <option value="CZ">Czechia</option>
                <option value="DK">Denmark</option>
                <option value="EE">Estonia</option>
                <option value="FI">Finland</option>
                <option value="FR">France</option>
                <option value="DE">Germany</option>
                <option value="HU">Hungary</option>
                <option value="IN">India</option>
                <option value="IE">Ireland</option>
                <option value="IT">Italy</option>
                <option value="JP">Japan</option>
                <option value="LV">Latvia</option>
                <option value="LT">Lithuania</option>
                <option value="LU">Luxembourg</option>
                <option value="MY">Malaysia</option>
                <option value="MX">Mexico</option>
                <option value="NL">Netherlands</option>
                <option value="NO">Norway</option>
                <option value="NZ">New Zealand</option>
                <option value="PL">Poland</option>
                <option value="PT">Portugal</option>
                <option value="PR">Puerto Rico</option>
                <option value="SG">Singapore</option>
                <option value="SK">Slovakia</option>
                <option value="SI">Slovenia</option>
                <option value="ES">Spain</option>
                <option value="SE">Sweden</option>
                <option value="CH">Switzerland</option>
                <option value="GB">United Kingdom</option>
                <option value="US" selected>United States</option>
                <option value="">Unknown</option>
              </select>
            </div>
          </div>

          <button id="validate-button" type="submit">Validate Address</button>

          <button id="clear-form-button" type="button" event="handleClearForm">Clear Form</button>

          <!-- Result Display Area -->
          <div id="result-container">
            <label for="result-display">Validation Result (formatted address and JSON)</label>
            <pre id="result-display">Result will appear here...</pre>
          </div>
        </form>
      </div>
    <!-- prettier-ignore -->
    <script>(g=>{var h,a,k,p="The Google Maps JavaScript API",c="google",l="importLibrary",q="__ib__",m=document,b=window;b=b[c]||(b[c]={});var d=b.maps||(b.maps={}),r=new Set,e=new URLSearchParams,u=()=>h||(h=new Promise(async(f,n)=>{await (a=m.createElement("script"));e.set("libraries",[...r]+"");for(k in g)e.set(k.replace(/[A-Z]/g,t=>"_"+t[0].toLowerCase()),g[k]);e.set("callback",c+".maps."+q);a.src=`https://maps.${c}apis.com/maps/api/js?`+e;d[q]=f;a.onerror=()=>h=n(Error(p+" could not load."));a.nonce=m.querySelector("script[nonce]")?.nonce||"";m.head.append(a)}));d[l]?console.warn(p+" only loads once. Ignoring:",g):d[l]=(f,...n)=>r.add(f)&&u().then(()=>d[l](f,...n))})
      ({key: "AIzaSyA6myHzS10YXdcazAFalmXvDkrYCp5cLc8", v: "beta"});</script>
  </body>
</html>

Try Sample