Sign in

Customization

Make the template yours — branding, marketing pages, blog and docs content, new providers and new apps.

zmlkit is built to be extended without fighting the framework: content is data, providers are registries, and every recipe below is additive.

Branding and copy

Marketing copy lives in the i18n dictionaries (web/src/i18n/), and the landing page is JSON-driven: web/src/marketing/content/home/<locale>.json describes the page as a list of typed blocks (hero, features, pricing, testimonials, FAQ, CTA, …). Changing copy or reordering sections means editing JSON — no React.

If you work with Claude Code, the repo ships a zmlkit-quick-start skill that takes a short project brief (name, domain, product description) and performs the first-pass rebrand for you.

SEO landing pages (no React)

A new keyword landing page is one registry entry plus one JSON file:

  1. Add the slug to LANDING_SLUGS in web/src/marketing/registry.ts.
  2. Create web/src/marketing/content/<slug>/en.json (plus optional per-locale files).

Routing, locale prefixes, hreflang, sitemap and the middleware rewrite pick it up automatically.

Blog and docs content

  • Blog posts are CMS rows (content_post with type='blog'), edited in the admin console under Content — categories, cover images, Markdown body, per-locale variants.
  • Docs (this site) are Markdown files in web/content/docs/. Add <slug>.md with title/description/order frontmatter; add <slug>.<locale>.md for translations. A build-time generator bundles them, so they work on every deploy target.
  • Updates (/updates) renders the repository CHANGELOG.md automatically.

Add an AI provider

One entry in web/src/server/ai/manager.ts (AI_PROVIDERS): implement generateTextStream and/or generateMedia (+ getMediaTask for async vendors) and declare capabilities. Credits, queueing, retries and refunds are handled by the shared pipeline.

Add a payment provider

One entry in web/src/server/billing/providers.ts (PAYMENT_PROVIDERS): implement createCheckout + parseWebhook. The registry drives the webhook route, default provider selection and signature verification. All providers normalize to one event type, so credits/subscriptions/refunds stay vendor-agnostic.

Add a new app (multi-app)

One deployment can host several products:

  1. Insert the app row (seed or admin console) and add the slug to ENABLED_APPS.
  2. Add its per-app secrets: APP_<SLUG>_STRIPE_SECRET_KEY, OAuth keys, etc.
  3. Give it a plan catalog entry in packages/core-domain/src/plans.ts.

Every business row carries app_id; clients send X-App-Id. The same email in different apps is a different user, and tokens are app-bound.

Going deeper

The full second-stage development guide (adding tables, endpoints, screens, locales) lives in the repository at docs/build-new-app.md, with a matching Claude Code skill (build-on-zmlkit).