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 in1f094c4) - packages/db/schema/mesh.ts: rename memberRelations → meshMemberRelations (missed inbeeaa3brename 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>
56 lines
1.2 KiB
TypeScript
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,
|
|
},
|
|
];
|
|
}
|