From 0076300a5629f34feb1fc20cca9af11360464212 Mon Sep 17 00:00:00 2001 From: Jonas Jesus Date: Tue, 18 Aug 2026 01:20:48 -0300 Subject: [PATCH] docs(renderJson): CORS is open by default (public data) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reflects decocms/blocks#476 — pageJsonCors now defaults to "*" (any origin, no credentials) since ?renderJson is public page data. A list restricts to credentialed origins; false disables. Co-Authored-By: Claude Opus 4.8 (1M context) --- client/src/content/v2/en/framework/render-json.mdx | 11 ++++++----- client/src/content/v2/pt/framework/render-json.mdx | 10 ++++++---- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/client/src/content/v2/en/framework/render-json.mdx b/client/src/content/v2/en/framework/render-json.mdx index 8185b7a..f2a4cee 100644 --- a/client/src/content/v2/en/framework/render-json.mdx +++ b/client/src/content/v2/en/framework/render-json.mdx @@ -67,7 +67,7 @@ Site-owned sections should prefer `export const renderJson = false` in their own ### Response contract - Envelope: `{ name, path, sections: [{ component, props }] }`. -- **CORS**: off by default — a native app needs none. Allow browser clients on other origins with `pageJsonCors` (see [Enabling / disabling](#enabling--disabling)). +- **CORS**: open by default (`Access-Control-Allow-Origin: *`, no credentials) — it's public page data, readable cross-origin like any public API. Restrict to credentialed origins, or turn it off, with `pageJsonCors` (see [Enabling / disabling](#enabling--disabling)). - **Secrets stripped**: any `Secret`-typed value (`{ get() }` or an unresolved secret block) is removed from the payload — a mobile app never receives one. A *plaintext* secret a loader put into a string prop can't be auto-detected, so keep secrets as `Secret` and never resolve them into a serialized prop. - **Caching**: an `ETag` over the serialized body — the app sends `If-None-Match` and gets `304` when the page is unchanged. - **Not found**: a stable `{ status: 404, notFound: true }` (HTTP 404). @@ -130,13 +130,14 @@ export default createDecoWorkerEntry(serverEntry, { renderJson: false, // disable ?renderJson site-wide asJson: false, // disable the legacy ?asJson - // Allow browser clients on other origins to read ?renderJson (native apps - // need none). Omit for same-origin only; use "*" for any origin (no credentials). - pageJsonCors: ["https://app.example.com"], + // CORS. Default (omit): open to any origin, no credentials — public page data. + // ["https://app.example.com"] → only these origins, *with* credentials. + // false → no CORS (same-origin + native apps only). + pageJsonCors: "*", }); ``` -With a flag off, that query param falls through to the normal HTML page. `renderJson`/`asJson` are the on/off switch for the **endpoint**; `pageJsonCors` controls **which origins** may read it from a browser; `renderJson.sectionsToIgnore` (on the Website app) controls *which sections* appear when it's on. +With a flag off, that query param falls through to the normal HTML page. `renderJson`/`asJson` are the on/off switch for the **endpoint**; `pageJsonCors` controls **which origins** may read it from a browser (open by default); `renderJson.sectionsToIgnore` (on the Website app) controls *which sections* appear when it's on. Migrated sites scaffold with `renderJson` and `asJson` **off** — opt in when you build an app. diff --git a/client/src/content/v2/pt/framework/render-json.mdx b/client/src/content/v2/pt/framework/render-json.mdx index ad19a98..f5a78cb 100644 --- a/client/src/content/v2/pt/framework/render-json.mdx +++ b/client/src/content/v2/pt/framework/render-json.mdx @@ -67,7 +67,7 @@ Seções do próprio site devem preferir `export const renderJson = false` no pr ### Contrato da resposta - Envelope: `{ name, path, sections: [{ component, props }] }`. -- **CORS**: desligado por padrão — app nativo não precisa. Libere clientes browser de outras origens com `pageJsonCors` (veja [Ativando / desativando](#ativando--desativando)). +- **CORS**: aberto por padrão (`Access-Control-Allow-Origin: *`, sem credentials) — é dado público de página, lido cross-origin como qualquer API pública. Restrinja a origens credenciadas, ou desligue, com `pageJsonCors` (veja [Ativando / desativando](#ativando--desativando)). - **Secrets removidos**: qualquer valor do tipo `Secret` (`{ get() }` ou um bloco de secret não-resolvido) é removido do payload — o app mobile nunca recebe um. Um secret em *plaintext* que um loader colocou num prop string não dá pra detectar automaticamente, então mantenha secrets como `Secret` e nunca os resolva num prop serializado. - **Cache**: um `ETag` sobre o body serializado — o app manda `If-None-Match` e recebe `304` quando a página não mudou. - **Não encontrado**: um envelope estável `{ status: 404, notFound: true }` (HTTP 404). @@ -131,12 +131,14 @@ export default createDecoWorkerEntry(serverEntry, { asJson: false, // desativa o ?asJson legado // Libera clientes browser de outras origens a ler o ?renderJson (app nativo - // não precisa). Omita para só-mesma-origem; use "*" para qualquer origem (sem credentials). - pageJsonCors: ["https://app.example.com"], + // CORS. Padrão (omitir): aberto pra qualquer origem, sem credentials — dado público. + // ["https://app.example.com"] → só essas origens, *com* credentials. + // false → sem CORS (só-mesma-origem + apps nativos). + pageJsonCors: "*", }); ``` -Com a flag desligada, aquele query param cai na página HTML normal. `renderJson`/`asJson` são o liga/desliga do **endpoint**; o `pageJsonCors` controla **quais origens** podem ler do browser; o `renderJson.sectionsToIgnore` (no app Website) controla *quais seções* aparecem quando ligado. +Com a flag desligada, aquele query param cai na página HTML normal. `renderJson`/`asJson` são o liga/desliga do **endpoint**; o `pageJsonCors` controla **quais origens** podem ler do browser (aberto por padrão); o `renderJson.sectionsToIgnore` (no app Website) controla *quais seções* aparecem quando ligado. Sites migrados nascem com `renderJson` e `asJson` **desligados** — ligue quando for fazer um app.