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>