Vercel was doing the apex->www 308 itself (its "redirect to www" project setting), so nothing about Cloudflare requires a redirect — the behaviour just disappears with Vercel. Rather than rebuild it with a zone Redirect Rule plus a proxied placeholder record, attach pcbjam.com as a SECOND custom domain on pcbjam-site. Both hosts serve the site and the pages already emit canonical=www, which is what consolidates them for search. That drops the riskiest artefact in the migration. Redirect Rules are zone-scoped and run BEFORE Workers/Pages routing, so a `contains` match instead of `eq` would 308 app./editor./demo./api. to www — breaking the product API, not just a marketing page. The sibling hosts are also the reason this was worth avoiding rather than merely guarding. APEX_MODE (lib/common.sh) selects the topology, defaulting to `serve`. 08-verify-prod.sh now dispatches through assert_apex: in serve mode it requires the apex to answer 200 with no hop, to not be a stale Vercel response, to declare canonical=www, and to expose /api/waitlist. The `redirect` mode and 07's rules/apex phases are kept for the alternative. 08 also checks the attached domains via wrangler rather than the REST API, so the whole serve-mode path needs only `wrangler login` — no zone scopes at all. Comments that explained themselves via the old redirect are corrected: astro.config.mjs, web/standalone/src/lib/config.ts and scripts/deploy/build-demo.mjs. The demo keeps posting to www — not because the apex redirects, but because a CORS preflight cannot follow one, so aiming at a host that might ever redirect is a latent breakage. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LAmkjM7okPdScp9XLW1JVr
43 lines
2.1 KiB
JavaScript
43 lines
2.1 KiB
JavaScript
// @ts-check
|
|
import { defineConfig } from 'astro/config';
|
|
import mdx from '@astrojs/mdx';
|
|
|
|
// Fully static: every page prerenders to HTML with zero client JS, and there is
|
|
// NO adapter — the build output in dist/ is what `wrangler pages deploy` ships.
|
|
// The one dynamic route, /api/waitlist, is a Cloudflare Pages Function in
|
|
// functions/ rather than an Astro SSR route. See README.md ("Deploying").
|
|
export default defineConfig({
|
|
// Canonical origin. Both www.pcbjam.com and the apex are custom domains on the
|
|
// same Pages project and serve identically, so this tag is what consolidates
|
|
// them for search — keep it pointing at www. Without `site` at all, prerendered
|
|
// Astro.url is localhost, which leaked into canonical/OG tags on production.
|
|
site: 'https://www.pcbjam.com',
|
|
output: 'static',
|
|
// Deliberately NO trailingSlash setting: Astro's default emits the canonical
|
|
// with a trailing slash, which is also the form Cloudflare Pages serves at
|
|
// 200 (the bare form 308s to it). Forcing 'never' would make canonical and
|
|
// the served URL disagree.
|
|
//
|
|
// MDX lets the Gerber-viewer blog post embed the <GerberDemo /> component
|
|
// inline (markdown posts can't import components).
|
|
integrations: [mdx()],
|
|
// Prefetch linked pages so SPA-style navigation feels instant.
|
|
prefetch: { prefetchAll: true, defaultStrategy: 'viewport' },
|
|
// Dev-server cross-origin isolation so the embedded Gerber viewer's WASM
|
|
// threads (SharedArrayBuffer) work under `npm run dev`. Production headers are
|
|
// scoped per-route in public/_headers. require-corp (not credentialless) for
|
|
// the widest browser support incl. Safari 15.2+; safe because the site loads
|
|
// only same-origin subresources.
|
|
vite: {
|
|
server: {
|
|
headers: {
|
|
'Cross-Origin-Opener-Policy': 'same-origin',
|
|
'Cross-Origin-Embedder-Policy': 'require-corp',
|
|
},
|
|
},
|
|
},
|
|
// No `env.schema`: the waitlist secrets are no longer read through
|
|
// `astro:env/server`. They reach the Pages Function as bindings on its
|
|
// `context.env` (`wrangler pages secret put`), and the two former schema
|
|
// defaults now live in functions/api/waitlist.ts.
|
|
});
|