Saltar al contenido principal

Clione + Hydrogen (Remix) Integration Guide

Render Clione SEO signals in a Shopify Hydrogen storefront.

Install

npm install @clione/seo

Hydrogen already queries Shopify's Storefront API. Add the clione.jsonld metafield to your product query — zero extra API calls.

1. Update your product query

query Product($handle: String!) {
product(handle: $handle) {
id
title
description
# ... existing fields
metafields(identifiers: [
{ namespace: "clione", key: "jsonld" },
{ namespace: "global", key: "description_tag" },
{ namespace: "global", key: "title_tag" }
]) {
namespace
key
value
}
}
}

2. Extract and render in your loader

// routes/products.$handle.tsx
import { createClioneSeo } from '@clione/seo'
import { json, type LoaderFunctionArgs } from '@shopify/remix-oxygen'

export async function loader({ params, context }: LoaderFunctionArgs) {
const { product } = await context.storefront.query(PRODUCT_QUERY, {
variables: { handle: params.handle },
})

const clione = createClioneSeo({ source: 'metafield' })
const signals = clione.extractSignals({
id: product.id,
metafields: product.metafields.filter(Boolean).map(m => ({
namespace: m.namespace,
key: m.key,
value: m.value,
})),
})

return json({ product, seoSignals: signals })
}

export default function ProductPage() {
const { product, seoSignals } = useLoaderData<typeof loader>()

return (
<>
{seoSignals.jsonLd && (
<script
type="application/ld+json"
dangerouslySetInnerHTML={{
__html: JSON.stringify(seoSignals.jsonLd),
}}
/>
)}
{/* product page content */}
</>
)
}

// In root.tsx meta function:
export const meta: MetaFunction<typeof loader> = ({ data }) => {
const signals = data?.seoSignals
return [
{ title: signals?.metaTitle ?? data?.product?.title },
{ name: 'description', content: signals?.metaDescription ?? '' },
]
}

Option B: API Mode

If you prefer not to modify your Storefront API queries:

// routes/products.$handle.tsx
import { createClioneSeo } from '@clione/seo'

export async function loader({ params, context }: LoaderFunctionArgs) {
const clione = createClioneSeo({
source: 'api',
apiUrl: context.env.CLIONE_API_URL,
apiKey: context.env.CLIONE_API_KEY,
platform: 'shopify',
})

const [product, signals] = await Promise.all([
context.storefront.query(PRODUCT_QUERY, { variables: { handle: params.handle } }),
clione.getSignals('product', params.handle),
])

return json({
product: product.product,
seoHead: clione.renderHead(signals),
})
}

Environment Variables

# Only needed for API mode
CLIONE_API_URL=https://your-clione-instance.com
CLIONE_API_KEY=sk-...

Why Metafield Mode Is Better for Hydrogen

Hydrogen already makes a Storefront API call for every product page. Adding 3 metafield identifiers to that query costs zero extra latency. API mode adds a second network call during SSR — still fast (cached), but unnecessary when the data is already in Shopify.

Supported Entity Types

Works for products, collections, and pages — any entity with Clione metafields.