You can create a checkout in Saleor using the checkoutCreate
mutation. We need to specify the email
address of the owner of this checkout, its initial content provided via lines
(this is a list of product variants along with their quantities) and the channel
.
graphql
folder and create a mutations
folder inside it.CheckoutCreate.graphql
file and copy/paste the mutation below.# graphql/mutations/CheckoutCreate.graphql
mutation CheckoutCreate {
checkoutCreate(
input: {
channel: "default-channel"
email: "customer@example.com"
lines: []
}
) {
checkout {
token
}
errors {
field
code
}
}
}
When you execute this mutation, an empty checkout will be created. In response to this checkout creation, we want to return the token
that will be used to refer to this checkout from the client. We also specify that the mutation should return errors if there are any.
Run the generate
script in the Terminal or make sure it's running in the watch
mode.
Open the GraphQL Playground and execute this mutation. You will see the token in the query results.
In our React.js application we need to trigger either creating a new checkout or reusing the existing one. In order to distinguish between new and returning user, we will keep the checkout token
client-side in the local storage. If the local storage is empty, it means there is no checkout yet and it must be created. Otherwise, we will use the token
that is kept in the local storage to ask the Saleor server to fetch an existing checkout.
For local storage management we will adopt useLocalStorage
hook from the react-use
which is a collection of essential React Hooks.
npm install react-use
or
pnpm add react-use
Let's use pages/_app.tsx
as a place to initialize the checkout in our React application. Since the checkout creation is performed via a GraphQL mutation, we need the GraphQL client to be already available within the React component tree. For that we will create a pass-through component called Root
that wraps the built-in Component
provided by Next.js. With such a setup in place, we will be able to use GraphQL queries and mutations at the top level.
pages/_app.tsx
file and update its contents:// pages/_app.tsx
import type { AppProps } from "next/app";
import { ApolloProvider } from "@apollo/client";
import { useEffect } from "react";
import { useLocalStorage } from "react-use";
import "../styles/main.css";
import { apolloClient } from "@/lib";
import { useCheckoutCreateMutation } from "@/saleor/api";
const Root = ({ Component, pageProps }: AppProps) => {
const [token, setToken] = useLocalStorage("token");
const [checkoutCreate, { data, loading }] = useCheckoutCreateMutation();
useEffect(() => {
async function doCheckout() {
const { data } = await checkoutCreate();
const token = data?.checkoutCreate?.checkout?.token;
setToken(token);
}
doCheckout();
}, [checkoutCreate, setToken]);
return <Component {...pageProps} token={token} />;
};
const MyApp = (props: AppProps) => (
<ApolloProvider client={apolloClient}>
<Root {...props} />
</ApolloProvider>
);
export default MyApp;
Root
reads the local storage to get the token of a checkout. If the token exists, it fetches an existing checkout, otherwise it creates a new one and sets its token in the local storage.
At this stage, the checkout session exists in the application state as long as you don't refresh the page. We will make this session persist between requests in the following sections.