API
Endpoint para consumir o conteúdo server-side e renderizá-lo diretamente no HTML da página — sem iframe, com SEO completo.
Quando usar a API
A integração via GTM carrega o conteúdo client-side (iframe ou Shadow DOM). Para lojas que precisam que o conteúdo seja indexado pelo Google e faça parte do HTML da página desde o primeiro byte, a solução é buscar o conteúdo no servidor e injetá-lo durante a renderização da página.
| Integração | SEO | Implementação |
|---|---|---|
| GTM (iframe) | Nenhum | Zero — só GTM |
| GTM (shadow) | Parcial | Zero — só GTM |
| API + SSR | Completo | Requer código no servidor |
Autenticação
A API aceita dois métodos de autenticação. O Bearer é o recomendado para chamadas server-side.
Bearer token Recomendado para SSR
Cada cliente com mode: "shadow" recebe uma API key gerada automaticamente pelo build. Passe-a no header Authorization:
Authorization: Bearer sk_a3f9b2c1d4e5...
A key é gerada na primeira vez que você roda node build.js após adicionar ou alterar o modo do cliente. Ela fica armazenada em clients.keys.json (gitignored) e no payload do KV (dist/kv-clients.json).
Referer Automático no browser
Para requisições de browser (GTM, tag.js), o header Referer é enviado automaticamente. O domínio precisa estar cadastrado e ativo no KV.
Endpoint
Parâmetros de path
| Parâmetro | Tipo | Descrição |
|---|---|---|
pageid | string | Identificador do template. Fornecido pela marca para cada produto. |
Headers da requisição
| Header | Obrigatório | Descrição |
|---|---|---|
Referer | Sim | URL completa da loja. O domínio precisa estar cadastrado. |
Resposta — modo iframe
Retornado quando o cliente está configurado com "mode": "iframe". Nesse caso, o HTML não é retornado — o cliente deve usar a URL pública do template.
{
"mode": "iframe"
}
Resposta — modo shadow
Retornado quando o cliente está configurado com "mode": "shadow". O HTML vem com todas as URLs de assets já reescritas para absolutas, pronto para injeção.
{
"mode": "shadow",
"html": "<style>...</style><div class=\"...\">...</div>"
}
Status de resposta
| Status | Situação |
|---|---|
| 200 | Acesso autorizado, resposta retornada |
| 403 | Domínio não cadastrado, inativo ou sem permissão para a marca |
| 404 | Template não encontrado ou marcado como inativo |
Exemplos de uso
cURL
curl https://content-descriptions.pages.dev/api/1025981 \
-H "Authorization: Bearer sk_..."
Node.js / fetch
const res = await fetch('https://content-descriptions.pages.dev/api/1025981', {
headers: {
Referer: 'https://minhaloja.com.br/produto/exemplo'
}
});
if (res.ok) {
const { mode, html } = await res.json();
if (mode === 'shadow' && html) {
// Injetar html no template da página
}
}
PHP
$response = file_get_contents('https://content-descriptions.pages.dev/api/1025981', false,
stream_context_create([
'http' => [
'header' => "Referer: https://minhaloja.com.br/produto/exemplo\r\n"
]
])
);
$data = json_decode($response, true);
if ($data['mode'] === 'shadow') {
echo $data['html'];
}
deco.cx — loader
// section/ProductDescription.tsx
export const loader = async (props, req) => {
const res = await fetch(
`https://content-descriptions.pages.dev/api/${props.pageid}`,
{ headers: { Referer: req.url } }
);
if (!res.ok) return { html: null };
const { mode, html } = await res.json();
return { html: mode === 'shadow' ? html : null };
};
Isolamento de CSS no SSR
Ao injetar o HTML server-side, o CSS do template pode vazar para o restante da página (e vice-versa), já que o Shadow DOM é um conceito do browser e não existe no servidor.
Estratégias para mitigar:
- Wrapper com escopo — envolva o HTML injetado em um elemento com um atributo único e use CSS scoping (
[data-bdesc]) nos estilos do template - Hidratação client-side — injete o HTML no SSR dentro de um custom element (
<brand-desc>) e use um script client-side para converter em Shadow DOM após a hidratação - CSS Modules no framework — se o framework suportar CSS Modules no servidor, extraia e escope os estilos durante o build