Shopify Checkout Extension to backend fetching
There are several posts around about people having issues figuring out how to send a fetch request from their checkout extension to their app backend (Remix). Shopify’s documentation around this is rather limited as well. So, I have put together a small example of how you can achieve this!
Assuming your extension was generated by the Shopify CLI, you should have a strucutre as such:
extensions/
[your-ext]/
Checkout.tsx
package.json
tsconfig.json
shopify.extension.toml
README.md
Create a new file in your extension directory called useSessionFetch.ts
and paste the following contents:
// extensions/[your-ext]/useSessionFetch.ts
import type { SessionToken } from "@shopify/ui-extensions/checkout";
/**
* Fetch using session token.
*
* @param sessionToken - Session token service.
*/
export default function useSessionFetch(sessionToken: SessionToken) {
/*
* Fetch resource.
*
* @param url - URL or request object for fetch.
* @param init - Configuration for fetch.
*/
return async function (url: string | URL | Request, init?: RequestInit) {
const token = await sessionToken.get();
return fetch(url, {
...(init || {}),
headers: {
...(init && init.headers ? init.headers : {}),
Authorization: `Bearer ${token}`,
},
});
};
}
This function will accept the session token service and return a function you can use instead of fetch
. Upon calling it, the code will automatically get a session token to append to the fetch request’s headers. Its really just a small but helpful hook to wrap around fetch
.
To utilize this in your extension, example:
// extensions/[your-ext]/Checkout.tsx
import { useSessionToken } from "@shopify/ui-extensions-react/checkout";
import useSessionFetch from "./useSessionFetch";
function Extension() {
const sessionToken = useSessionToken();
const sessionFetch = useSessionFetch(sessionToken);
useEffect(() => {
(async () => {
// Use `sessionFetch` instead of `fetch`
const response = await sessionFetch("/some/path/to/remix/backend");
if (response.ok) {
const { data } = await response.json();
setData(data);
}}
})();
}, []);
// ...
}
On your backend:
// routes/some.path.to.remix.backend
import { authenticate } from "../shopify.server";
import { json, type LoaderFunctionArgs } from "@remix-run/node";
export async function loader({ request, params }: LoaderFunctionArgs) {
const { sessionToken, cors } = await authenticate.public.checkout(request);
const shop = ShopDomain(sessionToken.dest);
// ...
return cors(json({
data: { hello: "world" },
}));
}
Now, with this hook, the token, and utilization of authenticate.public.checkout
, you can easily make a fetch request from your extension to your backend.