Skip to main content

JSON-LD escaping

Embedding JSON inside a <script> tag has a classic injection hazard: if any data field contains </script>, the browser terminates the script block there and executes whatever follows as HTML. Product titles, vendor names, and FAQ answers are all merchant- or user-influenced data. Every component and meta helper shipped in the SDK serializes through serializeJsonLd, which escapes every < to its JSON unicode form (\u003c). The output is still valid JSON — parsers read the escape back as < — but it can never close the script tag. This was verified with a hostile payload through a real app: a product name containing
renders inertly inside the JSON-LD block; no script breakout, and the structured data remains valid. If you write your own script tags (custom integrations using the core fetch helpers), never JSON.stringify straight into the tag:
(Remix and Hydrogen users don’t need this — the "script:ld+json" meta descriptor is serialized safely by the framework.)

The API key model

The SDK authenticates with your store API key (ask_…), sent as Authorization: Bearer. Unlike a public tag, this key is a secret — treat it like a password:
  • Server-side only. Use it in environment variables read on the server: generateMetadata, async server components, Remix/Hydrogen loaders, and route handlers all run on the server, so the shipped SDK never exposes it. Never put it in a NEXT_PUBLIC_* (or any client-exposed) variable, a client component, or a committed file.
  • Never in the browser or a client bundle. Anyone with the key can read your store’s SEO bundles. If it leaks (a public repo, a client bundle), rotate it immediately.
  • One key per store. A key resolves to exactly one connected store; a merchant with several stores has one key each.
This is also why the endpoints send Cache-Control: private — a per-store secret can’t be stored in a shared or CDN cache.

Rotating a key

Rotate a key any time in the dashboard under Settings → API Keys (this is also where you generate it the first time). After a rotation the previous key keeps working for 24 hours, so you can roll the new key out to your deployments without downtime. Update your AGENTSHOP_API_KEY env var and redeploy within that window.