Integrating w/ third parties

Integrating w/ third parties

The toolkit is a superset of Remix & Sanity, so you can use it with any other third party tool that supports either. The Shopify template is a great resource for understanding common patterns:

Fetching data from external systems on every request

For these cases, you should consider modifying app/routing/routeLoader.ts to fetch data in every request regardless of the document type being requested.

In the Shopify template, before returning the Sanity data, we fetch all referenced Shopify nodes and add them to the final data:

app/routing/routeLoader.ts
// ...
 
// ===== 6. FETCH REFERENCED SHOPIFY NODES' DATA =====
const dataWithShopifyNodes = await fetchReferencedShopifyNodes({
  data: dataWithAbTest,
  locale,
  request: context.request,
})
 
// ===== RETURN FINAL RESULT =====
return cachedResponse(dataWithShopifyNodes)

Fetching data on a per-route basis

For these, modify the specific document type resolver in app/routing/resolveRouteData.ts to fetch the data you need.

In the Shopify template, we fetch special data for collection & product documents:

app/routing/resolveRouteData.ts
export async function resolveRouteData(doc, context) {
  // ...
 
  switch (_type) {
    // ...
    case 'collection':
      const getSanityData = () =>
        configuredQuery({
          query: COLLECTION_ROUTE_QUERY,
          params: { docId: _id },
        })
 
      const [shopifyData, sanityData] = await Promise.all([
        loadShopifyProducts({
          request: context.request,
          collectionHandle: shopifyPathToHandle(doc.routePath, 'collection'),
          locale: locale ?? config.defaultLocale.value,
        }),
        getSanityData(),
      ])
 
      if (!shopifyData?.collection?.title) {
        throw 'Collection not found in Shopify'
      }
 
      return {
        shopify: shopifyData,
        ...sanityData,
      }
  }
}

API routes & data mutation

You can set-up Remix API routes (opens in a new tab) for mutating external data in your websites.

In the Shopify template, we use them to create & modify carts in the Storefront API, and save wishlists to session cookies.

app/routes/api.wishlist.ts
/** Saves the users' wishlist to their session cookie. */
export async function action({ request }: ActionArgs) {
  // ... Small subset as an example.
 
  session.set('wishlist', newList)
  headers.set('Set-Cookie', await commitSession(session))
 
  return json(
    {
      wishlist: newList,
    },
    { status: 200, headers },
  )
}

Displaying & interacting with data in the front-end

Use cases are so diverse here that we can't suggest much. Feel free to reach for npm packages, React Context, web storage APIs, etc.

In the Shopify template, the best example for this are user carts:

  1. query user cart in app/root.tsx
  2. feed it into CartContextProvider (through app/components/GlobalProviders.tsx)
  3. use it in any component with useCart()
  4. connect to the /api/cart route in CartContext's mutations (addToCart, updateCart, etc.)

Reach out if you're struggling with any specific integration you'd like to implement.