Files
imen_pishghaman/apps/web/nuxt.config.ts
T
S. EsmaeiliandClaude Opus 5.5 789d224ea0 feat: monorepo with NestJS API, admin panel and DB-driven website
Restructure the repo into a pnpm + Turborepo monorepo:

- apps/web: Nuxt 4 site, now server-rendered and reading all content
  from the API; pages cached with SWR and purged on content changes
- apps/api: NestJS 12 + Prisma 7 + PostgreSQL. Auth with short-lived
  access tokens and rotating httpOnly refresh cookies, roles (ADMIN,
  EDITOR), catalog, editable site sections, media upload to S3-compatible
  storage (converted to WebP), contact messages, audit log
- apps/admin: Vue 3 admin panel (Ant Design Vue, Pinia, Tailwind) for
  products, categories, site sections, messages, media and users
- packages/shared: Zod schemas and types shared by API and admin

Also:
- seed script that loads the original 8 categories / 89 products and
  section content
- Docker images for api (with a one-off migrate service), web, admin,
  and an nginx gateway for both domains
- dev and production compose files, daily database backup service
- API e2e tests

Removes the committed static out/ build and the old root Dockerfile.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-21 20:31:05 +03:30

78 lines
2.3 KiB
TypeScript

import tailwindcss from "@tailwindcss/vite";
import { siteConfig } from "./shared/config/site";
/** Pages are server-rendered and cached; the cache is dropped by the API after content changes. */
const PAGE_CACHE_SECONDS = 60;
export default defineNuxtConfig({
compatibilityDate: "2026-10-01",
ssr: true,
devtools: { enabled: false },
modules: ["@pinia/nuxt"],
css: ["~/assets/css/main.css", "~/assets/css/antd-overrides.css"],
app: {
head: {
htmlAttrs: { lang: siteConfig.lang, dir: siteConfig.dir },
bodyAttrs: {
class: "relative min-h-screen bg-bg font-sans text-ink antialiased",
},
charset: "utf-8",
viewport: "width=device-width, initial-scale=1",
link: [
{
rel: "preload",
href: "/fonts/IRANSansWebFaNum.woff2",
as: "font",
type: "font/woff2",
crossorigin: "",
},
{
rel: "preload",
href: "/fonts/IRANSansWebFaNum_Bold.woff2",
as: "font",
type: "font/woff2",
crossorigin: "",
},
{ rel: "icon", type: "image/svg+xml", href: siteConfig.favicon },
{ rel: "manifest", href: "/manifest.webmanifest" },
],
},
},
// overridable at runtime with NUXT_API_INTERNAL_URL, NUXT_REVALIDATE_SECRET, NUXT_PUBLIC_SITE_URL ...
runtimeConfig: {
/** API base URL used during server-side rendering (inside Docker: http://api:4000/api) */
apiInternalUrl: "http://localhost:4000/api",
/** shared secret the API sends to /_internal/revalidate */
revalidateSecret: "",
public: {
/** API base URL used by the browser (same origin, routed by nginx / the dev proxy) */
apiBase: "/api",
siteUrl: siteConfig.url,
},
},
routeRules: {
"/": { swr: PAGE_CACHE_SECONDS },
"/categories/**": { swr: PAGE_CACHE_SECONDS },
"/sitemap.xml": { swr: 3600 },
"/manifest.webmanifest": { swr: 3600 },
},
nitro: {
// in production nginx routes these paths; in dev the Nuxt server forwards them
devProxy: {
"/api": { target: "http://localhost:4000/api", changeOrigin: true },
"/media": { target: "http://localhost:9000/imen-media", changeOrigin: true },
},
},
vite: {
plugins: [tailwindcss()],
ssr: { noExternal: ["ant-design-vue", "@ant-design/icons-vue"] },
},
typescript: { strict: true },
});