Lob's website experience is not optimized for Internet Explorer.
Please choose another browser.

Engineering
May 26, 2022

Adding Address Autocomplete to Medusa.js Checkout

by 
Sid Maestre

Medusa.js is an open-source Shopify alternative built with JavaScript. It’s a great solution if you’re looking for a customizable ecommerce solution.

In this tutorial, we’ll see how to add Lob’s Address Autocomplete API feature to a Medusa project to give customers a faster checkout process.

You can find the complete code in this GitHub repo.

Why use address autocomplete?

Every bit of extra information that customers must enter in the checkout process adds to the likelihood of cart abandonment.

The information that takes the longest is undoubtedly the shipping address.

By using Lob’s Address Autocomplete API we can not only save time for customers but also validate addresses to reduce the possibility of errors.

Installing Medusa

In this tutorial, we’ll add the Lob Autocomplete React component to the checkout form found in the Medusa Next.js starter template.

To begin, you’ll need to install these two repos: 

You’ll find the installation instructions in the respective repos so we won’t repeat them here for the sake of brevity.

After installing, make sure you run the dev server on both projects (which run on ports 8000 and 9000 by default).

Set up Medusa for the US market

This walkthrough is designed for a US Storefront—though Lob has International Autocomplete support and could be used for non-US storefronts. We will need to make three adjustments so you get US dollars (USD) instead of Euros displayed in our starter store.

Seeding our store database

In your Medusa store project, open `my-medusa-store/data/seed.json`.

Swap the order of the regions, so NA (North America is first, and therefore the default).

 <script src="https://gist.github.com/lobot/2b60afcec0c62030f3cd0e1840a2a567.js"></script>

To seed your Medusa store run the following command:

<script src="https://gist.github.com/lobot/3bc45eae2662dcd632de242b744ebff6.js"></script>

Setting currency to USD

The default currency of the Next template is set to EUR. Let’s change that to USD as Lob’s autocomplete API generates US addresses while in test mode.

To do this, go to the frontend project (all our customizations will apply to the frontend) and change the `currencyCode` property to "usd" in the file context/store-context.js.

context/store-context.js

<script src="https://gist.github.com/lobot/54640a6ceb9649eb9b05e1b1b560e016.js"></script>

We’ll also need to change the default display from EUR to USD which we can do in the file components/checkout/shipping-method.jsx.

components/checkout/shipping-method.jsx

<script src="https://gist.github.com/lobot/061f9411c99a11ee56e5e3d967eae756.js"></script>

Adding autocomplete

The default checkout page of the Medusa store currently looks like this:

Our approach to adding address autocomplete will be:

  • Replace the “Address 1” field with the Lob autocomplete React component.
  • Add a “State” field (Medusa doesn’t provide this by default and it’s needed for US addresses).
  • When an address is selected through the autocomplete, programmatically fill the country, city, state, and postal code fields.

With this done, filling out the address form will be significantly faster—users only need to type a few characters to get a full address.

Creating address field component

The main component for the checkout form is in the file `components/checkout/information-step.jsx`. This is where you’ll find the address input that we’re going to replace with the address autocomplete component.

Let’s first make a copy of the `input-field` component and customize it to include the autocomplete. By doing it this way, we can keep the wrapper for error handling that is already present in the `input-field`.

To do this, go to terminal and copy the `input-field` component to a new component `address-field`: 

<script src="https://gist.github.com/lobot/a46a6f131dc0bd0184d5a5cb2425d5d1.js"></script>

In the new component file, rename the exported function from `InputField` to `AddressField`.

components/checkout/address-field.jsx

<script src="https://gist.github.com/lobot/f99199e255d2c00b1f73224e34f2689c.js"></script>

Adding autocomplete component

We’re now going to install Lob’s React address autocomplete component which provides a ready-to-use autocomplete, saving us from having to implement one from scratch.

Let’s first go to the terminal and install it with NPM. We add @previous so the component supports React 17 which is compatible with the Medusa starter project.

<script src="https://gist.github.com/lobot/ee93607aa1d21073421f8560019353aa.js"></script>

To use the autocomplete API, we’ll need a Lob API key. The instructions for generating one are outlined here.

Grab the publishable test key and add it to your .env.local file. We’ll use a variable name `NEXT_PUBLIC_LOB_PUBLISHABLE_KEY`. By prefixing it with NEXT_PUBLIC_ we can make it accessible from the frontend source code.

.env.local

<script src="https://gist.github.com/lobot/b63bd1ec6b46c0b499a9a9a20a56dce7.js"></script>

Now, open the component file `components/checkout/address-field.jsx` and import the Autocomplete component at the top of the file under the existing imports.

Then, create a variable apiKey and assign to it your publishable Lob API key. 

components/checkout/address-field.jsx

<script src="https://gist.github.com/lobot/3ecdcc51638f173d622e79e25a3b7e4b.js"></script>

We’ll then replace the Field component declaration here with the autocomplete component. To do that, locate where Field is declared in the JSX template.

components/checkout/address-field.jsx

<script src="https://gist.github.com/lobot/96772502476a19b051fdba6b7c065bfd.js"></script>

Replace that with the following:
components/checkout/address-field.jsx

<script src="https://gist.github.com/lobot/c8006f89915d9ded609ccc47a4b578fa.js"></script>

Adding address field to form

Let’s now add our newly created address field to the checkout form. The first thing we’ll do is import the component at the top of the file components/checkout/information-step.jsx.

components/checkout/information-step.jsx

<script src="https://gist.github.com/lobot/95eb0d2a742e27912fb57b24c3f69b3f.js"></script>

Next, in the same file, we’ll replace the address line 1 InputField component. You can identify it by the id address_1 .

components/checkout/information-step.jsx

<script src="https://gist.github.com/lobot/984d030a923a836b3d12e0a019d2af6c.js"></script>

Replace that with the following:

components/checkout/information-step.jsx

<script src="https://gist.github.com/lobot/c9f5c35aa6a27f80355ec2713ba438c7.js"></script>

Note that we keep the id, error, and errorMsg props but not the others as they aren’t relevant in our new address field.

Adding styling

To make the Lob autocomplete component fit with the Medusa checkout’s appearance we’ll need to add a few CSS rules.

Let’s create a CSS module in the styles directory called address.module.css.

<script src="https://gist.github.com/lobot/975d6ca710ee5d821334e7846b6e30fb.js"></script>

Put the following rules into that new file
styles/address.module.css

<script src="https://gist.github.com/lobot/a00d5fd3922e027b3577d026bfc3250d.js"></script>

Let’s now import the CSS module file into our address field component and apply the class addressStyle.address to the autocomplete component.

components/checkout/address-field.jsx
<script src="https://gist.github.com/lobot/6ef395b339a204069a48edf5ce84f086.js"></script>

With that done, the autocomplete component has now been integrated into the checkout. Go ahead and start typing into the form and you should see the address autocomplete working:

Setting up state field

As mentioned, the checkout form doesn’t include a field for the customer’s state by default. We’ll need this field as it’s required for US shipping addresses.

Although not in the form, the Medusa checkout API does include a field “province” which we should use for the state.

We’ll first create the field in the form’s validation schema which is handled by the library Yup. You’ll see the config object already has a value province that is set to be nullable. Let’s change this so it’s now required by removing nullable() and replacing it with `required("Required")`. 

components/checkout/information-step.jsx

<script src="https://gist.github.com/lobot/cdf26cd0e09baa2bc48b68db28abddea.js"></script>

The checkout also uses the form library Formik. This has a prop `initialValues` which allows the form to be pre-filled with saved values for returning customers.

Let’s add the province field to the `initialValues` by adding a property `province` and assigning to it `savedValues.province || ""`

components/checkout/information-step.jsx

<script src="https://gist.github.com/lobot/441ba459095b7370c14756870c11b702.js"></script>

Adding state field to template

We’ll now add the state (i.e., province) field to the form. We’ll make it share a row with the country field so the form is not too long.

To do this, find the field with id `country_code`. Wrap this in a div with className `styles.sharedrow`.

Add an `InputField` child with id `province`. You can make the placeholder “State” so it’s consistent with US addresses.

<script src="https://gist.github.com/lobot/5c4a27e4a32c5279f34f20caa9aa6fde.js"></script>

With that done, the form will now have a state field next to the country field.

Creating select handler

Looking again at the address autocomplete field, you’ll see that as we begin typing an address we get suggestions in a drop-down below.

When the user selects one of these suggestions, the autocomplete component calls an `onSelection` callback and passes the selected address to it.

Let’s create a handler function `handleSelect` and pass it to the `onSelection` prop. In this function, we’ll take the selected autocomplete address and populate the other address fields in the form.

The first thing we need to do is import the `useFormikContext` hook from the `formik` module. This gives us access to the form API in a functional component.

Let’s then destructure the object to get the `setFieldValue` method. 

components/checkout/address-field.jsx

<script src="https://gist.github.com/lobot/c80b49d13c6790fd0626ee3348bf49bd.js"></script>

Now we can define the callback function. This function will receive an object argument that has a property. This is itself an object with the full address components as sub properties.

Let’s now use the `setFieldValue` method in the callback to provide values for postal_code, city, province, address_1 and country_code.

<script src="https://gist.github.com/lobot/f3ef64046357bed9c8db35bb0088c8fd.js"></script>

Finally, we’ll assign handleSelect to the onSelection prop. We’ll also add the primaryLineOnly prop. What this does is ensure that when the user makes a selection that the entire address (with state, country, zip code, etc.) is not populated in the address field—just the primary line is e.g., “12 Test St”.

components/checkout/address-field.jsx 

<script src="https://gist.github.com/lobot/ab56a4a3acb911764fc33049bd88175c.js"></script>

Wrap up

With that done, we now have implemented a quick and stylish address autocomplete in Medusa! By typing a few characters into the autocomplete, customers get their validated address pre-filled, saving them a significant amount of time.