2026-10-06 16:28:05 +03:30
|
|
|
import { fileURLToPath } from "node:url";
|
|
|
|
|
import tailwindcss from "@tailwindcss/vite";
|
|
|
|
|
import { siteConfig } from "./shared/config/site";
|
2026-10-07 00:45:51 +03:30
|
|
|
import { categorySlugs } from "./shared/data/categories";
|
2026-10-06 16:28:05 +03:30
|
|
|
|
|
|
|
|
/** Unmatched path rendered through error.vue at build time and saved as out/404.html */
|
|
|
|
|
const NOT_FOUND_ROUTE = "/__not-found";
|
|
|
|
|
|
|
|
|
|
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",
|
2026-10-11 17:01:47 +03:30
|
|
|
href: "/fonts/IRANSansWebFaNum.woff2",
|
2026-10-07 00:45:51 +03:30
|
|
|
as: "font",
|
|
|
|
|
type: "font/woff2",
|
|
|
|
|
crossorigin: "",
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
rel: "preload",
|
2026-10-11 17:01:47 +03:30
|
|
|
href: "/fonts/IRANSansWebFaNum_Bold.woff2",
|
2026-10-06 16:28:05 +03:30
|
|
|
as: "font",
|
|
|
|
|
type: "font/woff2",
|
|
|
|
|
crossorigin: "",
|
|
|
|
|
},
|
|
|
|
|
{ rel: "icon", type: "image/svg+xml", href: siteConfig.favicon },
|
|
|
|
|
{ rel: "manifest", href: "/manifest.webmanifest" },
|
|
|
|
|
],
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
vite: {
|
|
|
|
|
plugins: [tailwindcss()],
|
|
|
|
|
ssr: { noExternal: ["ant-design-vue", "@ant-design/icons-vue"] },
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
// Static export (`npm run build` → ./out), served by nginx in Docker — same flow as the Next build.
|
|
|
|
|
nitro: {
|
|
|
|
|
output: { publicDir: fileURLToPath(new URL("./out", import.meta.url)) },
|
|
|
|
|
prerender: {
|
|
|
|
|
crawlLinks: false,
|
2026-10-07 00:45:51 +03:30
|
|
|
routes: [
|
|
|
|
|
"/",
|
|
|
|
|
"/robots.txt",
|
|
|
|
|
"/sitemap.xml",
|
|
|
|
|
"/manifest.webmanifest",
|
|
|
|
|
NOT_FOUND_ROUTE,
|
|
|
|
|
...categorySlugs.map((s) => `/categories/${s}`),
|
|
|
|
|
],
|
2026-10-06 16:28:05 +03:30
|
|
|
},
|
|
|
|
|
hooks: {
|
|
|
|
|
// Nuxt's own /404.html is an empty SPA shell. Replace it with a server-rendered error.vue
|
|
|
|
|
// (real content + noindex in the static HTML) produced by prerendering an unmatched route.
|
|
|
|
|
"prerender:generate"(route) {
|
|
|
|
|
if (route.route === "/404.html") route.skip = true;
|
|
|
|
|
if (route.route === NOT_FOUND_ROUTE && route.error?.statusCode === 404) {
|
|
|
|
|
route.error = undefined;
|
|
|
|
|
route.fileName = "/404.html";
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
typescript: { strict: true },
|
|
|
|
|
});
|