Welcome to Topiqu AI Blog! 👋
A modern full-stack TypeScript blogging platform. Topiqu pairs a rich Tiptap-based editor with xAI-powered content generation, real-time SSE notifications, multi-tenant client sites with custom domains, Stripe billing, and a robust permission layer authored in ZenStack.
- 📝 Rich Editor — Tiptap 3 with custom extensions (
Poll,slashCommand,indent), autosave, drafts, and quick release flow - 🤖 AI (xAI / Grok) — article generation, content enhancement, sentiment analysis, auto-image suggestions and LinkedIn post generator via
@ai-sdk/xai; token consumption metered perClientSiteplan - 🔔 Realtime — Server-Sent Events notification system with an event publisher
- 🏢 Multi-tenant client sites — per-tenant subdomains, custom apex domains with DNS (CNAME) verification, plan-gated white-labeling
- 💳 Billing — Stripe subscriptions (
PRO/PREMIUM) + ad-hoc token top-ups, webhook-driven plan changes, monthly / annual cycles - 🔐 Auth & Security —
@sidebase/nuxt-auth, argon2 hashing, OTP / 2FA (otplib),nuxt-security, DOMPurify, zxcvbn password strength, FingerprintJS, content-checker profanity filter - 🛡️ Row-level access control — ZenStack policies in
schema.zmodelenforced server-side viagetEnhancedPrisma(user) - 🌐 i18n — Full Czech / English localization (
@nuxtjs/i18n); Czech-language route slugs - 🎨 Theming — UnoCSS utility-first, SCSS partials, persisted theme store, custom emojis & branding (plan-gated)
- 🔎 SEO —
@nuxtjs/seo, dynamic OG images via Takumi, sitemap, schema.org metadata, priority indexing & sourcing per plan - 📊 Analytics & Charts — Chart.js + vue-chartjs,
nuxt-gtag(GA4), GAM ad integration,allowAdsplan gate - 📄 PDF / OG rendering — Playwright +
@sparticuz/chromium, Takumi, pdfkit, jspdf,nuxt-og-image - 📧 Transactional Email — MJML templates rendered and sent via AWS SES
- ☁️ AWS — S3 storage (uploads), Rekognition (image moderation), SES (mail)
- ⏱️ Scheduled tasks — Nitro
tasks/for community insights, cron-driven jobs (enableCrongate) - 📱 PWA — Installable, offline-capable via
@vite-pwa/nuxt - 🧩 Headless UI —
@headlessui/vue+@floating-ui/dom+ Tippy.js for accessible overlays, dropdowns, dialogs - ... and more
| Layer | Technology |
|---|---|
| Framework | Nuxt 4 (Vue 3.5, Composition API) |
| Language | TypeScript (strict) |
| Styling | UnoCSS + SCSS |
| i18n | @nuxtjs/i18n — en, cs |
| Auth | @sidebase/nuxt-auth + Prisma adapter |
| ORM / Schema | Prisma 6 + ZenStack v2 (access policy) |
| Database | PostgreSQL (via Docker Compose) |
| Editor | Tiptap 3 with custom extensions |
| AI | Vercel AI SDK + @ai-sdk/xai (Grok) |
| Billing | Stripe via @unlok-co/nuxt-stripe (subscriptions + token top-ups) |
| SEO | @nuxtjs/seo, nuxt-og-image, nuxt-gtag |
| Cloud | AWS (S3, Rekognition, SES), Stripe, Vercel |
| Testing | Vitest + @nuxt/test-utils + happy-dom |
| Tooling | ESLint, Prettier, vue-tsc |
app/ Nuxt app layer (pages, components, composables, stores, layouts)
server/ Nitro server (API routes, scheduled tasks, utils)
shared/ Cross-cutting code (zod schemas, utils) shared by app & server
prisma/ ZenStack source (schema.zmodel), generated Prisma schema, migrations
extensions/ Custom Tiptap editor extensions
emails/ MJML email templates
i18n/ Locale files (en, cs)
types/ Ambient TS types
public/ Static assets
See MAP.md for the complete architecture reference — it is the single source of truth.
Requirements
- 📦 Bun (recommended) — Node-compatible package manager & runtime
- 🐳 Docker — used by
predevto spin up PostgreSQL - 🔑 A configured
.env(Auth, AWS, Stripe, AI keys, etc.)
Install & run in dev mode
bun install # installs deps + runs `nuxt prepare`
bun zenstack:generate # generates Prisma schema from schema.zmodel
bun prisma:deploy # applies migrations to the DB
bun dev # spins up Postgres via docker, starts Nuxt dev serverDatabase management
bun db:up # start Postgres container
bun db:down # stop Postgres container
bun db:reset # wipe volumes & restart fresh
bun db:seed # seed initial dataBuild
bun run build # server build (zenstack generate + prisma deploy + nuxt build)
bun generate # static site generation
bun preview # preview production buildbun test # run vitest once
bun test:watch # watch mode
bun test:coverage # coverage report (v8)
bun typecheck # vue-tsc strict typecheckESLint (@nuxt/eslint) + Prettier are enforced project-wide.
bun lint # check
bun lint:fix # auto-fix
bun prettier # check formatting
bun prettier:fix # apply formatting
bun fmt # lint:fix + prettier:fix- Follow the rules in
CLAUDE.md— Staff-Level Nuxt 4 / Vue 3.5 standards. - Every structural change must be reflected in
MAP.md. - All user-facing strings must use
$t('key')— no raw text in templates. - Prefer Vue 3.5 macros (
defineModel,useTemplateRef, …) and VueUse composables over manualref()/reactive(). - Vue SFC order:
<template>first, then<script setup lang="ts">, then<style>(avoid<style>blocks whenever possible — prefer pure UnoCSS). - Server API: prefer the ZenStack-enhanced client (
getEnhancedPrisma(user)) over rawprismaso access policies fromschema.zmodelare enforced — fall back to rawprismaonly when policies must be bypassed intentionally. - Error responses: use
createError({ statusCode, message })with i18n keys viauseServerI18nwhere applicable. - Don't "modernize" without reason — keep changes terse and scoped to the task; refactors require explicit approval.
- Significant changes should be covered by Vitest tests.
Made with ❤️ by @bigjohnn1 & @germondai