Files
claudemesh/apps/web/src/app/sitemap.ts
Alejandro Gutiérrez 84e14ff410 feat(web): marketing landing page with Anthropic design system
Landing page at / matching claude.com/product/claude-code structure:
hero, surfaces, pricing, laptop-to-laptop, features, meets-you, faq, cta,
+ floating "Latest news" toaster. Motion-based scroll reveals.

Design system extracted from claude.com via playwriter reverse-engineering:
- Self-hosted Anthropic Sans/Serif/Mono fonts (6 woff2 files)
- --cm-* tokens in globals.css (clay #d97757, gray-050..900, fluid clamps)
- Serif display, Sans UI, Mono terminals & section markers
- Italic clay phrases for emphasis

Header rewritten for design consistency: claudemesh wordmark (mesh glyph +
serif), dark bg, nav (Docs · Pricing · Changelog · GitHub), "Start free" CTA.

Free-first messaging: hero subhead "Free and open-source. Forever.", primary
CTA "Start free", pricing defaults to Solo=Free.

Fixes:
- packages/api: comment out aiRouter (module removed in 1f094c4)
- packages/db/schema/mesh.ts: rename memberRelations → meshMemberRelations
  (missed in beeaa3b rename pass, caught via web build — ack'd by BotMou)
- credits/{api,server,index}: stub out @turbostarter/ai/credits/utils
- remove (marketing)/legal/[slug] route and common/mdx.tsx (cms-backed)
- sitemap: drop blog/legal enumeration (cms removed)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-04 22:09:38 +01:00

56 lines
1.2 KiB
TypeScript

import { getPathname, config } from "@turbostarter/i18n";
import { appConfig } from "~/config/app";
import { pathsConfig } from "~/config/paths";
import type { MetadataRoute } from "next";
const url = (path: string) => `${appConfig.url}${path}`;
const getEntry = (path: string) => ({
url: url(
getPathname({
path,
locale: appConfig.locale,
defaultLocale: appConfig.locale,
}),
),
alternates: {
languages: Object.fromEntries(
config.locales.map((locale) => [
locale,
url(
getPathname({
path,
locale,
defaultLocale: appConfig.locale,
}),
),
]),
),
},
});
export default function sitemap(): MetadataRoute.Sitemap {
return [
{
...getEntry(pathsConfig.index),
lastModified: new Date(),
changeFrequency: "monthly",
priority: 1,
},
{
...getEntry(pathsConfig.marketing.pricing),
lastModified: new Date(),
changeFrequency: "monthly",
priority: 0.8,
},
{
...getEntry(pathsConfig.marketing.contact),
lastModified: new Date(),
changeFrequency: "monthly",
priority: 0.8,
},
];
}