Adding Address Autocomplete to Medusa.js Checkout

Adding Address Autocomplete to Medusa.js Checkout

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.

To seed your Medusa store run the following command:

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

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

Adding autocomplete

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

default checkout page

Our approach to adding address autocomplete will be:

  1. Replace the “Address 1” field with the Lob autocomplete React component.

  2. Add a “State” field (Medusa doesn’t provide this by default and it’s needed for US addresses).

  3. 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 the terminal and copy the input-field component to a new component address-field:

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

components/checkout/address-field.jsx

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.

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

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

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

Replace that with the following:

components/checkout/address-field.jsx

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

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

Replace that with the following:

components/checkout/information-step.jsx

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.

Put the following rules into that new file:

styles/address.module.css

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

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:

example of 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

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

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.

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

checkout form with state 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

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.

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

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.

final checkout form with all fields