Skip to content

Repository files navigation

deCDN — marketing site

A decentralized delivery layer for bytes at scale. Anyone can serve bytes; clients pay per megabyte in USDC.

Next.js 16React 19Tailwind CSS v4TypeScript 6pnpmCloudflare PagesConventional CommitsCode style: Prettier

This is the source for the deCDN marketing site and blog.

Stack

Next.js 16 (App Router) · React 19 · Tailwind CSS v4 · TypeScript · pnpm. Static export, deployed to Cloudflare Pages.

Getting started

pnpm install # required (not npm/yarn) — husky hooks shell out to `pnpm exec`
pnpm dev # dev server on :3000
pnpm build # static export → ./out
pnpm test# vitest run
pnpm typecheck # tsc --noEmit
pnpm lint # eslint (flat config)
pnpm format # prettier --write .

Project layout

  • app/ — App Router entry (layout.tsx, page.tsx, globals.css) plus the blog routes (blog/, blog/[slug]/), the legal/[doc] route, the sitemap/robots handlers, the llms.txt / llms-full.txt handlers, and file-convention metadata assets.
  • components/site/ — page sections composed by app/page.tsx (Hero, Compare, Method, Faq, Contact, …) plus chrome (Chrome, Footer, ScrollReveal, …).
  • components/ui/ — low-level primitives (Frame, SectionHeader, Prose, Figure, …).
  • lib/ — shared helpers (links.ts, copy.ts, blog.ts, faq.ts, legal.ts, jsonld.tsx, schema.ts, …). The site's prose and its displayed values live in lib/copy.ts as plain data — the comparison table maps over it and the llms-full.txt mirror serialises it, so anything inlined in a component drifts from the mirror.
  • test-utils/ — test-only helpers for walking the element tree a server component returns.
  • scripts/check-out.mjs, postbuild assertions run against ./out by pnpm build.
  • content/blog/ — MDX posts loaded by lib/blog.ts and rendered by app/blog/[slug]/page.tsx.
  • content/legal/ — MDX for the legal pages (privacy, terms, disclaimer), loaded by lib/legal.ts and rendered by app/legal/[doc]/page.tsx.
  • docs/ — Mintlify source for docs.decdn.org. Built and deployed independently of pnpm build; not part of the static export and not imported from the website code.
  • Path alias: @/* maps to the project root (e.g. @/lib/links, not @/src/...).

Gotchas

  • Static export only.next.config.ts sets output: "export"; the build emits ./out. No SSR, ISR, middleware, or Image Optimization API. Route handlers (app/robots.txt/route.ts, app/sitemap.xml/route.ts, app/sitemap-pages.xml/route.ts, app/llms.txt/route.ts, app/llms-full.txt/route.ts) must be dynamic = "force-static" and GET-only; the dotted segment is what makes them emit real files rather than <path>/index.html. robots.txt is a hand-written route handler rather than the Next app/robots.ts metadata file, so it can emit the non-standard Content-Signal: directive (per contentsignals.org).
  • trailingSlash: true. Every route emits <path>/index.html. Internal links and hand-built URLs (sitemap entries, JSON-LD @ids) should expect a trailing slash — see SITE_URL and BLOG_URL in lib/links.ts.
  • Tailwind v4. Theme tokens live in app/globals.css under @theme inline { … } — there is no tailwind.config.*.
  • Conventional commits enforced.commitlint runs in the commit-msg husky hook; non-conforming messages are rejected.
  • metadataBase is live.lib/links.tssite is the real origin and INDEXABLE is true. Anything anchored on this origin — OG and canonical (via metadataBase); JSON-LD and the sitemap/robots emitters (via SITE_URL) — ships to production. Adding a non-blog page means appending an entry to app/sitemap-pages.xml/route.ts; blog posts are auto-derived from content/blog/, while legal pages are driven by the closed LEGAL_SLUGS list in lib/legal.ts (add both the MDX file under content/legal/ and a slug there). Flipping INDEXABLE flips <meta name="robots"> only; robots.txt and the sitemap stay unconditional by design (rationale in lib/links.ts).
  • Machine-readable surfaces./llms.txt is a curated index of this origin and /llms-full.txt is every page as one plain-text document; both derive their page entries from listPosts(), LEGAL_SLUGS, lib/faq.ts and lib/copy.ts, are listed in app/sitemap-pages.xml/route.ts, and are advertised through alternates.types in app/layout.tsx and a Link: header in public/_headers. scripts/check-out.mjs resolves every advertised same-origin URL against out/ after a build. The protocol documentation has its own pair on docs.decdn.org, served by Mintlify.

Deploy

Cloudflare Pages serves the out/ directory produced by pnpm build.

Agent contributors

See AGENTS.md for the full ruleset (CLAUDE.md is a one-line include of it).

About

Marketing site for deCDN — the delivery layer anyone can serve.

Resources

Stars

3 stars

Watchers

0 watching

Forks

Used by

Contributors

Languages