Blog

Enforcing Verified Addresses with the Address Verification Flow Component (AVFC)

Overview

This guide is a supplementary recipe for customers who have already installed the Address Verification Flow Component (AVFC) managed package (pw_avfc) and are familiar with embedding it in a custom LWC. For general setup and embedding instructions, refer to the ProvenWorks article: Implementing the AVFC in a Custom LWC.

By default, the addressVerificationFlowBaseComponent allows users to either select a verified address from the search results or manually enter/edit an address. There is no built-in attribute to disable manual entry entirely.

However, you can achieve the same outcome by combining two features of the component:

  1. The status field — tracks whether the address was selected from verification search ("Verified") or manually entered/edited ("Not checked").
  2. Custom CSS — hides the status field from the user so they cannot tamper with it.

Your wrapper LWC then checks the status value before allowing the user to proceed, effectively enforcing that only verified addresses are accepted.


How It Works

When use-status is set to true on the component:

  • Selecting an address from the verification search sets the status to "Verified".
  • Manually entering or editing any address field (street, city, state, etc.) resets the status to "Not checked".

This means that even if a user selects a verified address and then modifies it, the status will revert to "Not checked", ensuring the final address is only considered verified if it was accepted as-is from the search results.


Step-by-Step Implementation

Step 1: Create a Custom CSS Static Resource

Create a CSS file that hides the status field. The status field’s wrapper element has the CSS class status applied to it, so you can target it with:

.status {
    display: none;
}

Upload this file as a Static Resource in your Salesforce org (Setup → Static Resources → New). For example, name it addressVerificationHideStatus.

Note: This static resource lives in your org, not inside the managed package. The AVFC component’s additional-styles attribute accepts a path to any static resource in your org.

Step 2: Create Your Wrapper LWC

Create a new LWC that wraps the managed package component. This wrapper will:

  • Enable the status field via use-status
  • Inject the custom CSS to hide the status field via additional-styles
  • Listen for addresschange events to track the current status
  • Validate that the status is "Verified" before allowing the user to proceed

Important: Because the AVFC is installed as a managed package with the namespace pw_avfc, you must reference it as <pw_avfc-address-verification-flow-base-component> in your template — not <c-address-verification-flow-base-component>.

Template (enforceVerifiedAddress.html)

<template>
    <pw_avfc-address-verification-flow-base-component
        country={country}
        state={state}
        postal-code={postalCode}
        city={city}
        street={street}
        street2={street2}
        use-status
        additional-styles="/resource/addressVerificationHideStatus"
        main-label={mainLabel}
        country-label={countryLabel}
        state-label={stateLabel}
        postal-code-label={postalCodeLabel}
        city-label={cityLabel}
        street-label={streetLabel}
        search-button-label={searchButtonLabel}
        manual-button-label={manualButtonLabel}
        onaddresschange={handleAddressChange}
    ></pw_avfc-address-verification-flow-base-component>

    <template if:true={showValidationError}>
        <div class="slds-notify slds-notify_alert slds-alert_error slds-m-top_small" role="alert">
            <span class="slds-assistive-text">Error</span>
            <h2>Please select a verified address from the search results before continuing.
                Manually entered or edited addresses are not accepted.</h2>
        </div>
    </template>

    <div class="slds-m-top_medium">
        <lightning-button
            variant="brand"
            label="Continue"
            onclick={handleContinue}
        ></lightning-button>
    </div>
</template>

Controller (enforceVerifiedAddress.js)

import { LightningElement, api, track } from 'lwc';

export default class EnforceVerifiedAddress extends LightningElement {
    @api country = '';
    @api state = '';
    @api postalCode = '';
    @api city = '';
    @api street = '';

    @api mainLabel = 'Address';
    @api countryLabel = 'Country';
    @api stateLabel = 'State/Province';
    @api postalCodeLabel = 'Zip/Postal Code';
    @api cityLabel = 'City';
    @api streetLabel = 'Street';
    @api searchButtonLabel = 'Verify Address';
    @api manualButtonLabel = 'Enter Manually';

    @track currentStatus = 'Not checked';
    @track showValidationError = false;

    handleAddressChange(event) {
        const address = event.detail.address;

        // Update local field values
        for (const [key, value] of Object.entries(address)) {
            if (this[key] !== undefined) {
                this[key] = value;
            }
        }

        // Track the status value
        if (address.status) {
            this.currentStatus = address.status;
        }

        // Clear the error as soon as the user takes action
        this.showValidationError = false;
    }

    handleContinue() {
        if (this.currentStatus !== 'Verified') {
            this.showValidationError = true;
            return;
        }

        // Status is "Verified" — proceed with your logic
        this.showValidationError = false;

        // Example: dispatch an event, navigate, save, etc.
        this.dispatchEvent(new CustomEvent('verified', {
            detail: {
                country: this.country,
                state: this.state,
                postalCode: this.postalCode,
                city: this.city,
                street: this.street,
            }
        }));
    }
}

Meta Configuration (enforceVerifiedAddress.js-meta.xml)

<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>65.0</apiVersion>
    <isExposed>true</isExposed>
    <masterLabel>Enforce Verified Address</masterLabel>
    <targets>
        <target>lightning__RecordPage</target>
        <target>lightning__AppPage</target>
        <target>lightning__HomePage</target>
    </targets>
</LightningComponentBundle>

How the Validation Logic Works

User Action status Value Validation Result
Selects an address from verification search "Verified" ✅ Passes
Clicks “Enter Manually” and types an address "Not checked" ❌ Blocked
Selects a verified address, then edits a field "Not checked" ❌ Blocked

Why This Works

Any manual change to an address field (other than the status dropdown itself) resets the status to "Not checked":

changeHandler(e) {
    if (e.target.name !== 'status') {
        this.status = 'Not checked';
        this.template.querySelector('[data-id="select"]').value = 'Not checked';
    }
    // ...dispatches addresschange event with updated status
}

When an address is selected from the verification search, the status is set to "Verified":

if (this.useStatus) {
    this.status = address.status;
    this.notChecked = this.status === 'Not checked';
    this.verified = this.status === 'Verified';
    addressParts.push('status');
    this.updateSelectedOption();
}

Because the status field is hidden via CSS, the user cannot manually override it — the only way to achieve "Verified" is by selecting an address from the search results.


Summary

  1. Set use-status on the pw_avfc-address-verification-flow-base-component to enable status tracking.
  2. Create a static resource in your org with .status { display: none; } and pass its path to additional-styles to hide the status dropdown from users.
  3. In your wrapper LWC, listen to the addresschange event, read event.detail.address.status, and block progression unless the value is "Verified".

Prerequisites