Add a shipping method with pickup points
In this guide, we'll go through the steps needed to retrieve pickup points from GraphQL and display them in a Map using Front-Commerce's component.
This method can also be useful if you are planning to set up a Store Locator in your shop.
If you are willing to display these pickups in the checkout this guide will help you. However if you are willing to save the needed information in the user's quote, please have a look at Use custom shipping information instead.
To go through this guide, you'll need to have a created a new extension with a GraphQL module and to know how to fetch data in a component.
Add pickups to your GraphQL Schema
The goal here is to be able to fetch a list of pickups from GraphQL. You could
create your own types and your custom implementation. However, in
Front-Commerce, we've created a GraphQL interface named FcPickup
that ensures
that any pickup point can be displayed in the PostalAddressSelector component of
Front-Commerce.
Display the list of pickup points
Now that you have the list of pickup points available in GraphQL, it is now
possible to display them in your application. This can be done by using the
component theme/components/organisms/PostalAddressSelector
.
To do so, you need to first retreive the list of pickup from GraphQL. This can be done by using this query:
#import "theme/components/organisms/PostalAddressSelector/PostalAddressSelectorFragment.gql"
query PickupListQuery {
pickupList {
...PostalAddressSelectorFragment
}
}
To retrieve this data, we will be using an API route:
import { FrontCommerceApp } from "@front-commerce/remix";
import { json } from "@front-commerce/remix/node";
import { PickupListQueryDocument } from "~/graphql/graphql";
export async function loader({ request, context }) {
const app = new FrontCommerceApp(context.frontCommerce);
const pickupList = await app.graphql.query(PickupListQueryDocument);
// In the real world application, you would have to also handle potential errors
return json(pickupList.pickupList);
}
Once you have the data, you can use it in your component with the
useApiFetcher
hook:
import { useApiFetcher } from "@front-commerce/remix/react";
import PickupListQuery from "./PickupListQuery.gql";
import PostalAddressSelector from "theme/components/organisms/PostalAddressSelector";
import type { loader } from "routes/api.pickupList";
const PickupList = () => {
const { data, loading, error } =
useApiFetcher<typeof loader>("/api/pickupList");
const [activeLocation, setActiveLocation] = useState(null);
const [activeLocationIntention, setActiveLocationIntention] = useState(null);
if (loading) {
return <div>Loading...</div>;
}
if (error) {
return <div>Error...</div>;
}
return (
<PostalAddressSelector
activeLocation={activeLocation}
activeLocationIntention={activeLocationIntention}
setActiveLocation={setActiveLocation}
setActiveLocationIntention={setActiveLocationIntention}
locations={data.locations}
/>
);
};
export default PickupList;
Please note here that we're using the activeLocation
and the
activeLocationIntention
. The difference between those two is that the
activeLocation
is only set if the user explicitly clicked on the button that
allows them to choose a pickup point. The intention is triggered if they've
clicked on the map's marker or on the address of the pickup. This allows to fine
tune the UX depending on your pickup selector needs.
activeLocation
though is entirely optional and you can rely on
activeLocationIntention
instead.
Final words
Please keep in mind that this feature is built for shipping purpose in priority. This means that you may need additional work to make it work with a custom store locator page for instance. But it shouldn't be too much work and would allow you to have the same behaviors in both your store locator and your checkout.
Moreover, by using this method, this also means that you are only a step away from adding a click & collect shipping method (provided you have the existing logistics in your business).
If you have any questions, please contact us. We are eager to support more use cases.