Skip to content

Shopify behind your storefront

The common shape: you render your own storefront in Next.js and query Shopify’s Storefront API for the catalogue. Geoffy sits alongside, reading the products Shopify already synced to it.

What makes this easy: the handle Shopify gives you is the handle Geoffy wants. You already have it in scope on the product page, so there is nothing to map and nothing to store.

app/products/[handle]/page.tsx
import { notFound } from "next/navigation";
import { GeoffyProduct } from "@geoffy/headless/next";
import { getProductByHandle } from "@/lib/shopify";
const canonical = (handle: string) => `https://yourdomain.com/products/${handle}`;
export async function generateMetadata({ params }) {
const { handle } = await params;
const product = await getProductByHandle(handle);
if (!product) return {};
return {
title: product.title,
description: product.description,
// Geoffy publishes against this exact URL. If it is missing or wrong,
// every product fails with `canonical_broken`.
alternates: { canonical: canonical(handle) },
};
}
export default async function ProductPage({ params }) {
const { handle } = await params;
const product = await getProductByHandle(handle);
if (!product) notFound();
return (
<article>
<ProductGallery images={product.images} />
<h1>{product.title}</h1>
<BuyBox variantId={product.variants[0].id} price={product.priceRange} />
<ProductDescription html={product.descriptionHtml} />
{/* Same handle Shopify gave us. Same canonical generateMetadata declared. */}
<GeoffyProduct
siteKey={process.env.GEOFFY_SITE_KEY!}
handle={handle}
canonicalUrl={canonical(handle)}
/>
</article>
);
}
  1. Shopify is the source of product facts. Title, price, availability, variants — your storefront reads them from the Storefront API, as it already does.

  2. Geoffy is a supplement, not a replacement. Its structured data deliberately carries no offers, no price and no availability, because your page already has a product node with those and two prices on one page with no rule for which wins is worse than one. Geoffy adds what the commerce node lacks: positive notes, audience, attributes, certifications.

  3. You do not sync anything. Shopify already pushed your catalogue to Geoffy when you connected the store. You generate and publish in the dashboard.

If you also run a themed Shopify storefront, that is a separate integration and both can be live at once — they serve different domains. On this domain, the package is the whole integration; nothing in your Shopify theme affects it.

Everything else — the root files, the namespace, robots.txt, the IndexNow key — is identical whether Shopify is behind you or not. Follow the quickstart.