Skip to content

Repository files navigation

NumeraSheets — shop window

Marketing site for the NumeraSheets shop: a home page listing every spreadsheet template, one page per product, and a free calculator. It never takes a payment — buying happens on the shop, and every outbound link is built in one place so it stays trackable.

Stack

Next.js 16 (App Router) · React 19 · Tailwind CSS v4 · TypeScript. Type is Archivo + IBM Plex Mono; the palette is the shop's own ink navy and gold.

Running it

npm install
npm run dev

Domains, and the duplicate-content trap

Live on numerasheets.com, served by Cloudflare Pages (the site left Vercel on 2026-09-04 — see MIGRACAO-VERCEL-CLOUDFLARE.md in the workspace).

Host What happens Why
numerasheets.com serves the site the canonical host
www.numerasheets.com 301 → apex, path and query preserved measured 2026-09-09; the redirect rule lives in the Cloudflare dashboard, not in this repo — see below
numerasheets-site.pages.dev 200 + X-Robots-Tag: noindex the Pages host must keep working for deploy previews, so it is not redirected — only kept out of the index. Rule lives in public/_headers

The canonical tag is what keeps this safe, and it needs no host logic: SITE_URL in lib/products.ts is absolute, so every page declares https://numerasheets.com/... no matter which host served it. Verified by fetching www and pages.dev directly — both return the apex canonical.

Why the www redirect is not in this repo

Static export has no redirects() and no headers() — there is no server to run them. Everything that used to live in next.config.ts had to move: headers became public/_headers, which Cloudflare Pages reads.

Redirects cannot follow the same path: Cloudflare's _redirects file is path-based only and explicitly does not support domain-level redirects. A www → apex redirect has to be a Redirect Rule / Bulk Redirect in the Cloudflare dashboard, not a file in this repo. Do not try to express it in _redirects; it will silently never match — which is why looking for it here and finding nothing does not mean it is missing.

It is in place. Measured on 2026-09-09:

https://www.numerasheets.com/templates/debt-payoff-tracker?utm_source=pinterest
  -> 301 https://numerasheets.com/templates/debt-payoff-tracker?utm_source=pinterest

Permanent, and it preserves path and query — which is what campaign links need, since they carry ?utm_source=. Test it from the command line, not the browser: host-level routing is invisible to a normal page load.

This paragraph used to read "until that rule exists, www is a duplicate host held in check by the canonical tag alone." The rule was created and the warning stayed — an orphaned note, the same failure mode already recorded in .claude/rules/etsy-titulo.md. A note that justifies the absence of something has to be re-read when that something arrives, or the next review spends its time chasing a problem that is already solved.

Notes

  • Product data lives in lib/products.ts. listingUrl() is the only place a shop URL is built and productUrl() the only place a page URL is, so the BUY_ON switch can move the whole catalogue between shops in one line.
  • The home page's product count, the price ceiling and the keywords list are all derived from that array. Numbers written by hand drift; these have.
  • The bundle is in products but is not a template. It carries kind: "bundle", which keeps it out of templates — the list the catalogue counts and renders as cards. It still gets a page, a sitemap entry and a keyword, because those come from products. Without the flag the heading would read "Thirteen templates" while listing twelve, counting the eleven inside the bundle a second time. It also renders as its own offer block rather than a card, because a set sells on the saving it names.
  • Listing images in public/shots/ are renders of the real workbooks, resized from the artwork used on the shop listings themselves. They are generated by Products/_shared/export_card_shots.py in the workspace repo, never by hand.
  • app/opengraph-image.png must be captured from the deployed production URL, never from next dev — the dev server injects a floating indicator.

About

Shop window for the NumeraSheets Etsy shop: a responsive Next.js page for eight spreadsheet templates, linking out to Etsy.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages