Best Practices
AI Web Launcher ships with a rule pack in ai_rules/rules/. This page condenses the most important rules so you (and your AI assistant) keep the codebase clean. The full, enforceable versions live in ai_rules/rules/*.md.
Next.js 15
- Async dynamic APIs.
params,searchParams,headers(), andcookies()return Promises. Alwaysawaitthem in Server Components andgenerateMetadata. - Server Components by default. Add
"use client"only when you need state, effects, or browser APIs. Push interactivity to small leaf components. - Env-gate every integration. Never assume a key exists. Guard client init so a missing variable disables the feature instead of crashing the build.
page.tsx
export default async function Page(props: {
params: Promise<{ slug: string }>;
}) {
const { slug } = await props.params;
// ...
}SEO
getSEOTags()on every page. Eachapp/*/page.tsxexportsmetadatavia the helper in@/libs/seo, with acanonicalUrlRelative.- Structured data. Use
renderStructuredData()for JSON-LD (Organization, WebSite, SoftwareApplication). - Sitemap.
next-sitemapruns onpostbuild. Keepnext-sitemap.config.jspointed at your production domain.
page.tsx
export const metadata = getSEOTags({
title: "Page Title — Your Brand",
description: "120–160 chars including the primary keyword.",
canonicalUrlRelative: "/page-path",
});Design
- Every animation has a job. Highlight, guide flow, give feedback, or showcase content. No decoration on decoration.
- Honor
prefers-reduced-motion. CSS animations are covered globally inglobals.css; gate JS/canvas motion with theuseReducedMotion()hook. - Centralize tokens. Colors, spacing, and easing live in the
@themeblock inapp/globals.css. Don't hardcode hex values in components.
Performance budget
- Animate only
transform,opacity,clip-path,filter— they are GPU-composited. Avoid animatingwidth,height,top/left,box-shadow, orbackground-position. - Accordions: animate
grid-template-rows: 0fr → 1fr, nevermax-height. - Avoid
transition-all. Use explicit lists liketransition-[transform,opacity]. - Lazy-load heavy client libs with
next/dynamic. Addprefetch={false}to<Link>s pointing at heavy routes from the homepage. - Declare
browserslistinpackage.jsonto drop legacy polyfills, and runANALYZE=true pnpm buildbefore merging perf-sensitive changes.
TypeScript
- No
any. PreferRecord<string, unknown>or a real type. Use optional chaining on typed globals (window.gtag?.()). interfacefor object shapes,typefor unions.- Import types separately:
import type { User } from "@supabase/supabase-js";
Let the rules drive the AI
Point Claude Code at
ai_rules/rules/ and CLAUDE.md at the start of a session. The rules are written as enforceable instructions, not suggestions.