Skip to main content

@agentshop/seo/next/proxy

Wraps Next’s proxy (middleware on Next 15 and below) to report AI-crawler requests. An existing handler passed as the first argument runs first and its response is returned untouched — and it may return nothing, matching Next’s own proxy contract, in which case NextResponse.next() is used. Reporting is deferred with event.waitUntil, and the bot check runs before it, so a human page view never extends the invocation. See AI crawler visibility.

@agentshop/seo/next (App Router)

All App Router helpers default to ISR caching ({ next: { revalidate: 3600 } }), overridable via config.fetchOptionsexcept AgentShopPixel, which caches separately (see below). Metadata helpers support Next 14 (sync params) and Next 15/16 (Promise params).

Analytics

Server component that loads the storefront analytics script through Next’s <Script strategy="afterInteractive">. Render once in your root layout. Returns null when the pixel isn’t configured or the endpoint is unreachable. Caches via unstable_cache for 5 minutes.
This lowers the route’s revalidate window to 5 minutes on any route whose window is longer. unstable_cache applies its revalidate to the surrounding prerender work unit, so rendering AgentShopPixel in your root layout pulls every page’s ISR window down to 300s.That is deliberate, not incidental: the script URL is baked into the rendered HTML, so on an ISR route the token can only be as fresh as the page around it. A 5-minute config cache inside hourly HTML would serve a token that stopped working 55 minutes ago — the failure this component exists to remove. Routes already revalidating faster than 300s are unaffected.If you’d rather keep a longer window, render the tag yourself from fetchPixelConfig() and accept a token that can be stale for that window.
config.fetchOptions is forwarded to the fetch, except cache, which this helper pins to no-store so the unstable_cache window above is the only cache in play. The resolved script URL is only rendered if it’s https: — an http: URL is dropped rather than emit a mixed-content script tag. See Storefront analytics.

Metadata

Ready generateMetadata for app/products/[handle]/page.tsx:
Factory for a configured generateMetadata. Use this whenever you pass config — it avoids the positional-argument collision with Next’s generateMetadata(props, parent) call signature.
Collection equivalents, same signatures and behavior.
All App Router metadata omits og:type"product" isn’t in Next’s typed Metadata union and throws at runtime. All other Open Graph tags render with property="og:*".

Components

Async server components. Each renders an escaped <script type="application/ld+json">, or null when the bundle is unavailable. SiteJsonLd belongs on the home page only.

Routes

Route-handler factory for app/sitemap.xml/route.ts:
Responds 200 XML or 502 empty. Sets Content-Type: application/xml; charset=utf-8 (no Cache-Control header — caching is via ISR).

Re-exports

The bundle → Metadata mapper, for wiring metadata yourself — see Core API.

@agentshop/seo/next/pages (Pages Router)

getServerSideProps helper — reads the handle from route params and returns the bundle as a seo prop.
Renders the full tag set into next/head: title, description, canonical, Open Graph (including og:type=product — raw meta accepts it), Twitter, and the escaped JSON-LD script. Renders nothing for null.
Handler factory for pages/sitemap.xml.ts or an API route:
Responds 200 XML or 502 empty; sets Content-Type: application/xml; charset=utf-8 and Cache-Control: public, max-age=3600, stale-while-revalidate=86400.

Remix and Hydrogen exports

Documented in their framework guides: Remix (loadProductSeo(handle, config?), agentshopProductMeta, productSitemapLoader) and Hydrogen (same names, but loadProductSeo(context, handle, config?) and a context-aware sitemap loader).