fimo 0.13.0 → 0.14.0-staging.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/assets/content-templates/types-template.eta +3 -29
  2. package/assets/skills/fimo-cli/references/content.md +7 -0
  3. package/assets/skills/fimo-cli/references/deploy.md +11 -0
  4. package/assets/skills/fimo-cli/references/project-vars-and-secrets.md +6 -2
  5. package/assets/skills/fimo-code/SKILL.md +7 -0
  6. package/assets/skills/fimo-code/references/content/clients.md +9 -1
  7. package/assets/skills/fimo-code/references/content/schema.md +14 -1
  8. package/assets/skills/fimo-code/references/frameworks/hosting.md +91 -0
  9. package/assets/skills/fimo-code/references/frameworks/next/app-router.md +1 -1
  10. package/assets/skills/fimo-code/references/frameworks/next.md +32 -3
  11. package/assets/skills/fimo-code/references/frameworks/react-router.md +7 -0
  12. package/assets/skills/fimo-code/references/frameworks/vite-react.md +8 -7
  13. package/assets/skills/fimo-code/references/ui.md +19 -0
  14. package/assets/skills/fimo-studio/references/cms.md +4 -1
  15. package/dist/build/next/config.d.ts +14 -0
  16. package/dist/build/next/config.js +34 -0
  17. package/dist/build/vite/plugins/server-config.js +15 -2
  18. package/dist/cli/bundle.json +1 -1
  19. package/dist/cli/index.js +91 -91
  20. package/dist/runtime/app/FimoScripts.js +2 -2
  21. package/dist/runtime/iframe/ScreenshotProvider.js +1 -1
  22. package/dist/runtime/next/labels.d.ts +1 -1
  23. package/dist/runtime/next/labels.js +1 -1
  24. package/dist/runtime/next/server-runtime.js +3 -3
  25. package/dist/runtime/primitives/lib/image-optimization.d.ts +3 -3
  26. package/dist/runtime/react-router/preset.d.ts +30 -0
  27. package/dist/runtime/react-router/preset.js +33 -0
  28. package/dist/runtime/seo/buildSeoForPath.d.ts +16 -16
  29. package/dist/runtime/shared/fimo-config.server.js +5 -0
  30. package/dist/runtime/shared/fimo-config.types.d.ts +20 -0
  31. package/dist/runtime/templates.d.ts +1 -1
  32. package/dist/scripts/validate-fimo-config.d.ts +5 -0
  33. package/dist/scripts/validate-fimo-config.js +29 -0
  34. package/dist/scripts/validate-route-metadata.js +1 -1
  35. package/package.json +11 -2
  36. package/release.json +2 -2
  37. package/templates/react-router/.fimo/config.json +1 -0
  38. package/templates/react-router/_gitignore +1 -0
  39. package/templates/react-router/package.json +5 -5
  40. package/templates/react-router/react-router.config.ts +2 -0
  41. package/templates/react-router/tsconfig.json +5 -6
@@ -1,4 +1,4 @@
1
- import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
1
+ import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  // @ts-ignore - virtual module provided by fimoConfigPlugin in fimo/vite
3
3
  import rawConfig from 'virtual:fimo-config';
4
4
  // @ts-ignore - virtual module provided by overlayPlugin in fimo/vite; empty in prod
@@ -44,5 +44,5 @@ export function FimoScripts() {
44
44
  // @ts-ignore - import.meta.env is a Vite feature
45
45
  const previewScriptUrl = import.meta.env.VITE_PREVIEW_SCRIPT_URL;
46
46
  const siteSchemas = buildSiteSchemas();
47
- return (_jsxs(_Fragment, { children: [runtime ? _jsx("script", { type: "module", dangerouslySetInnerHTML: { __html: runtime } }) : null, previewScriptUrl ? _jsx("script", { type: "module", src: previewScriptUrl }) : null, siteSchemas.map((schema, index) => (_jsx("script", { type: "application/ld+json", dangerouslySetInnerHTML: { __html: JSON.stringify(schema) } }, index)))] }));
47
+ return (_jsxs(_Fragment, { children: [runtime ? _jsx("script", { type: "module", dangerouslySetInnerHTML: { __html: runtime } }) : null, previewScriptUrl ? _jsx("script", { src: previewScriptUrl }) : null, siteSchemas.map((schema, index) => (_jsx("script", { type: "application/ld+json", dangerouslySetInnerHTML: { __html: JSON.stringify(schema) } }, index)))] }));
48
48
  }
@@ -1,4 +1,4 @@
1
- import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
1
+ import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { useIsFetching } from '@tanstack/react-query';
3
3
  import { useCallback, useEffect, useRef } from 'react';
4
4
  // Wait for all running CSS/JS animations to complete
@@ -1,7 +1,7 @@
1
1
  import { type GetLabelsOptions } from '../labels/fetch.js';
2
2
  /**
3
3
  * Read the labels for an application-resolved locale. When omitted, locale
4
- * comes from FIMO_DEFAULT_LOCALE / NEXT_PUBLIC_FIMO_DEFAULT_LOCALE.
4
+ * comes from the runtime's default-locale variable.
5
5
  */
6
6
  export declare function getLabels(options?: GetLabelsOptions): Promise<import("./client.js").Labels>;
7
7
  //# sourceMappingURL=labels.d.ts.map
@@ -2,7 +2,7 @@ import { fetchLabels } from '../labels/fetch.js';
2
2
  import { nextServerContentRuntime } from './server-runtime.js';
3
3
  /**
4
4
  * Read the labels for an application-resolved locale. When omitted, locale
5
- * comes from FIMO_DEFAULT_LOCALE / NEXT_PUBLIC_FIMO_DEFAULT_LOCALE.
5
+ * comes from the runtime's default-locale variable.
6
6
  */
7
7
  export function getLabels(options) {
8
8
  return fetchLabels(nextServerContentRuntime, options);
@@ -1,14 +1,14 @@
1
1
  import { requireContentApiUrl } from '../content/client/runtime.js';
2
2
  export const nextServerContentRuntime = {
3
3
  apiBase() {
4
- return requireContentApiUrl(process.env.FIMO_API_URL ?? process.env.NEXT_PUBLIC_FIMO_API_URL, 'FIMO_API_URL or NEXT_PUBLIC_FIMO_API_URL');
4
+ return requireContentApiUrl(process.env.FIMO_CONTENT_API_URL, 'FIMO_CONTENT_API_URL');
5
5
  },
6
6
  defaultLocale() {
7
- return process.env.FIMO_DEFAULT_LOCALE?.trim() || process.env.NEXT_PUBLIC_FIMO_DEFAULT_LOCALE?.trim() || 'en';
7
+ return process.env.FIMO_DEFAULT_LOCALE?.trim() || 'en';
8
8
  },
9
9
  headers(extra) {
10
10
  const headers = { ...extra };
11
- const env = process.env.FIMO_ENV?.trim() || process.env.NEXT_PUBLIC_FIMO_ENV?.trim();
11
+ const env = process.env.FIMO_ENV?.trim();
12
12
  if (env) {
13
13
  headers['X-Fimo-Env'] = env;
14
14
  }
@@ -1,19 +1,19 @@
1
1
  import type { ComponentPropsWithoutRef } from 'react';
2
2
  /** Default host suffixes eligible for Cloudflare Image Resizing optimization. */
3
- export declare const DEFAULT_IMAGE_HOST_SUFFIXES: readonly [".fimo.team", ".fimo.ai", ".fimo.site"];
3
+ export declare const DEFAULT_IMAGE_HOST_SUFFIXES: readonly ['.fimo.team', '.fimo.ai', '.fimo.site'];
4
4
  /**
5
5
  * Get allowed host suffixes from env or use defaults.
6
6
  * Env format: comma-separated suffixes, e.g. ".fimo.team,.fimo.ai,.fimo.site"
7
7
  */
8
8
  export declare function parseImageHostSuffixes(value: string | undefined): readonly string[];
9
9
  export declare const DEFAULT_IMAGE_QUALITY = 85;
10
- export declare const DEFAULT_IMAGE_FIT: "scale-down";
10
+ export declare const DEFAULT_IMAGE_FIT: 'scale-down';
11
11
  export declare const DEFAULT_IMAGE_DPRS: readonly [1, 2];
12
12
  /**
13
13
  * Supported `fit` modes for image optimization.
14
14
  * These map to Cloudflare Image Resizing `fit` parameter.
15
15
  */
16
- export declare const IMAGE_FIT_VALUES: readonly ["scale-down", "contain", "cover", "crop", "pad"];
16
+ export declare const IMAGE_FIT_VALUES: readonly ['scale-down', 'contain', 'cover', 'crop', 'pad'];
17
17
  export type ImageFit = (typeof IMAGE_FIT_VALUES)[number];
18
18
  /** Clamp quality to valid range [1, 100], defaulting to 85. */
19
19
  export declare function clampQuality(quality: number | undefined): number;
@@ -0,0 +1,30 @@
1
+ interface ReactRouterUserConfig {
2
+ readonly ssr?: boolean;
3
+ }
4
+ interface ReactRouterBuildEndArgs {
5
+ readonly buildManifest: unknown;
6
+ readonly reactRouterConfig: unknown;
7
+ readonly viteConfig: {
8
+ readonly root: string;
9
+ readonly build: {
10
+ readonly assetsDir?: string;
11
+ };
12
+ };
13
+ }
14
+ /**
15
+ * Connect a client-rendered React Router build to Fimo hosting.
16
+ *
17
+ * The hosting-provider build contract stays inside Fimo so applications do not
18
+ * install or import provider packages. SSR needs a deeper server-runtime
19
+ * adapter and is rejected until Fimo supports that contract explicitly.
20
+ */
21
+ export declare function fimoPreset(): {
22
+ name: string;
23
+ reactRouterConfig({ reactRouterUserConfig }: {
24
+ reactRouterUserConfig: ReactRouterUserConfig;
25
+ }): {
26
+ buildEnd({ buildManifest, reactRouterConfig, viteConfig }: ReactRouterBuildEndArgs): void;
27
+ };
28
+ };
29
+ export {};
30
+ //# sourceMappingURL=preset.d.ts.map
@@ -0,0 +1,33 @@
1
+ import { mkdirSync, writeFileSync } from 'node:fs';
2
+ import { dirname, join } from 'node:path';
3
+ const REACT_ROUTER_BUILD_RESULT = '.vercel/react-router-build-result.json';
4
+ /**
5
+ * Connect a client-rendered React Router build to Fimo hosting.
6
+ *
7
+ * The hosting-provider build contract stays inside Fimo so applications do not
8
+ * install or import provider packages. SSR needs a deeper server-runtime
9
+ * adapter and is rejected until Fimo supports that contract explicitly.
10
+ */
11
+ export function fimoPreset() {
12
+ return {
13
+ name: 'fimo',
14
+ reactRouterConfig({ reactRouterUserConfig }) {
15
+ if (reactRouterUserConfig.ssr !== false) {
16
+ throw new Error('fimoPreset() currently supports React Router apps configured with ssr: false');
17
+ }
18
+ return {
19
+ buildEnd({ buildManifest, reactRouterConfig, viteConfig }) {
20
+ const buildResultPath = join(viteConfig.root, REACT_ROUTER_BUILD_RESULT);
21
+ const assetsDir = viteConfig.build.assetsDir;
22
+ const result = {
23
+ buildManifest,
24
+ reactRouterConfig,
25
+ viteConfig: assetsDir ? { build: { assetsDir } } : undefined,
26
+ };
27
+ mkdirSync(dirname(buildResultPath), { recursive: true });
28
+ writeFileSync(buildResultPath, `${JSON.stringify(result, null, 2)}\n`);
29
+ },
30
+ };
31
+ },
32
+ };
33
+ }
@@ -3,35 +3,35 @@ export declare function getSeoForPath(pathname: string, routeData?: unknown): Fi
3
3
  export declare function buildMetaForPath(pathname: string, routeData?: unknown): ({
4
4
  title: string;
5
5
  name?: undefined;
6
- content?: undefined;
7
6
  property?: undefined;
7
+ content?: undefined;
8
8
  tagName?: undefined;
9
9
  rel?: undefined;
10
10
  href?: undefined;
11
11
  } | {
12
+ title?: undefined;
12
13
  name: string;
13
14
  content: string;
14
- title?: undefined;
15
15
  property?: undefined;
16
16
  tagName?: undefined;
17
17
  rel?: undefined;
18
18
  href?: undefined;
19
19
  } | {
20
- property: string;
21
- content: string;
22
20
  title?: undefined;
23
21
  name?: undefined;
22
+ property: string;
23
+ content: string;
24
24
  tagName?: undefined;
25
25
  rel?: undefined;
26
26
  href?: undefined;
27
27
  } | {
28
- tagName: string;
29
- rel: string;
30
- href: string;
31
28
  title?: undefined;
32
29
  name?: undefined;
33
- content?: undefined;
34
30
  property?: undefined;
31
+ content?: undefined;
32
+ tagName: string;
33
+ rel: string;
34
+ href: string;
35
35
  })[];
36
36
  export declare function buildFimoMeta(args: {
37
37
  location: {
@@ -41,34 +41,34 @@ export declare function buildFimoMeta(args: {
41
41
  }): ({
42
42
  title: string;
43
43
  name?: undefined;
44
- content?: undefined;
45
44
  property?: undefined;
45
+ content?: undefined;
46
46
  tagName?: undefined;
47
47
  rel?: undefined;
48
48
  href?: undefined;
49
49
  } | {
50
+ title?: undefined;
50
51
  name: string;
51
52
  content: string;
52
- title?: undefined;
53
53
  property?: undefined;
54
54
  tagName?: undefined;
55
55
  rel?: undefined;
56
56
  href?: undefined;
57
57
  } | {
58
- property: string;
59
- content: string;
60
58
  title?: undefined;
61
59
  name?: undefined;
60
+ property: string;
61
+ content: string;
62
62
  tagName?: undefined;
63
63
  rel?: undefined;
64
64
  href?: undefined;
65
65
  } | {
66
- tagName: string;
67
- rel: string;
68
- href: string;
69
66
  title?: undefined;
70
67
  name?: undefined;
71
- content?: undefined;
72
68
  property?: undefined;
69
+ content?: undefined;
70
+ tagName: string;
71
+ rel: string;
72
+ href: string;
73
73
  })[];
74
74
  //# sourceMappingURL=buildSeoForPath.d.ts.map
@@ -15,8 +15,13 @@ export function getConfigServer(rootDir) {
15
15
  try {
16
16
  const configPath = resolveFimoConfigPath(rootDir);
17
17
  const content = readFileSync(configPath, 'utf-8');
18
+ // `fimo validate` owns strict config validation. The public runtime only
19
+ // reads the already-validated values and must stay self-contained: importing
20
+ // the repository-private API contracts package would break installed apps.
18
21
  const raw = JSON.parse(content);
19
22
  return {
23
+ runtime: raw.runtime,
24
+ hosting: raw.hosting,
20
25
  seo: raw.seo,
21
26
  i18n: raw.i18n,
22
27
  routes: raw.routes,
@@ -1,3 +1,21 @@
1
+ export type FimoFramework = 'astro' | 'nextjs' | 'nuxtjs' | 'react-router' | 'remix' | 'sveltekit' | 'vite' | 'vue';
2
+ export interface FimoRuntimeCommands {
3
+ dev?: string;
4
+ build?: string;
5
+ install?: string;
6
+ }
7
+ export interface FimoRuntimeConfig {
8
+ framework?: FimoFramework;
9
+ commands?: FimoRuntimeCommands;
10
+ outputDirectory?: string;
11
+ }
12
+ export interface FimoHostingRewrite {
13
+ source: string;
14
+ destination: string;
15
+ }
16
+ export interface FimoHostingConfig {
17
+ rewrites?: FimoHostingRewrite[];
18
+ }
1
19
  export interface FimoSEO {
2
20
  title?: string;
3
21
  description?: string;
@@ -53,6 +71,8 @@ export interface FimoI18nConfig {
53
71
  routing?: FimoI18nRoutingConfig;
54
72
  }
55
73
  export interface FimoConfig {
74
+ runtime?: FimoRuntimeConfig;
75
+ hosting?: FimoHostingConfig;
56
76
  seo?: FimoSEO;
57
77
  i18n?: FimoI18nConfig;
58
78
  routes?: Record<string, FimoRouteConfig>;
@@ -1,4 +1,4 @@
1
- export declare const TEMPLATE_FRAMEWORKS: readonly ["react-router", "astro", "next", "vite"];
1
+ export declare const TEMPLATE_FRAMEWORKS: readonly ['react-router', 'astro', 'next', 'vite'];
2
2
  export type TemplateFramework = (typeof TEMPLATE_FRAMEWORKS)[number];
3
3
  export declare const DEFAULT_TEMPLATE: TemplateFramework;
4
4
  /**
@@ -0,0 +1,5 @@
1
+ export interface ValidateFimoConfigResult {
2
+ errors: string[];
3
+ configChecked: boolean;
4
+ }
5
+ export declare function validateFimoConfig(cwd: string): ValidateFimoConfigResult;
@@ -0,0 +1,29 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ import { FimoAppConfigSchema } from '@fimo/api-contracts';
4
+ import { resolveFimoConfigPath } from '../runtime/shared/fimo-config.server.js';
5
+ export function validateFimoConfig(cwd) {
6
+ const configPath = resolveFimoConfigPath(cwd);
7
+ if (!fs.existsSync(configPath)) {
8
+ return { errors: [], configChecked: false };
9
+ }
10
+ const displayPath = path.relative(cwd, configPath).replaceAll(path.sep, '/');
11
+ let value;
12
+ try {
13
+ value = JSON.parse(fs.readFileSync(configPath, 'utf8'));
14
+ }
15
+ catch {
16
+ return { errors: [`${displayPath} must contain valid JSON.`], configChecked: true };
17
+ }
18
+ const parsed = FimoAppConfigSchema.safeParse(value);
19
+ if (parsed.success) {
20
+ return { errors: [], configChecked: true };
21
+ }
22
+ return {
23
+ errors: parsed.error.issues.map((issue) => {
24
+ const pointer = issue.path.length > 0 ? `#${issue.path.join('.')}` : '';
25
+ return `${displayPath}${pointer}: ${issue.message}`;
26
+ }),
27
+ configChecked: true,
28
+ };
29
+ }
@@ -33,6 +33,7 @@ export function validateRouteMetadata(options = {}) {
33
33
  const srcDir = path.resolve(cwd, 'src');
34
34
  const routesFilePath = path.resolve(srcDir, 'routes.ts');
35
35
  const errors = [];
36
+ const config = readJson(configFilePath);
36
37
  // Parse routes from src/routes.ts (file → path mapping)
37
38
  let fileRoutes = [];
38
39
  if (!fs.existsSync(routesFilePath)) {
@@ -49,7 +50,6 @@ export function validateRouteMetadata(options = {}) {
49
50
  pathToFile.set(fr.path, fr.file);
50
51
  }
51
52
  }
52
- const config = readJson(configFilePath);
53
53
  const i18n = validateI18nConfig(config);
54
54
  errors.push(...i18n.errors);
55
55
  const configRoutes = loadConfigRoutes(config);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fimo",
3
- "version": "0.13.0",
3
+ "version": "0.14.0-staging.1",
4
4
  "description": "Fimo CLI - create, deploy, and manage Fimo projects",
5
5
  "bin": {
6
6
  "fimo": "dist/cli/index.js"
@@ -34,6 +34,11 @@
34
34
  "types": "./dist/runtime/next/client.d.ts",
35
35
  "import": "./dist/runtime/next/client.js"
36
36
  },
37
+ "./next/config": {
38
+ "types": "./dist/build/next/config.d.ts",
39
+ "import": "./dist/build/next/config.js",
40
+ "require": "./dist/build/next/config.js"
41
+ },
37
42
  "./react-router": {
38
43
  "types": "./dist/runtime/react-router/index.d.ts",
39
44
  "import": "./dist/runtime/react-router/index.js"
@@ -42,6 +47,10 @@
42
47
  "types": "./dist/runtime/react-router/routes.d.ts",
43
48
  "import": "./dist/runtime/react-router/routes.js"
44
49
  },
50
+ "./react-router/preset": {
51
+ "types": "./dist/runtime/react-router/preset.d.ts",
52
+ "import": "./dist/runtime/react-router/preset.js"
53
+ },
45
54
  "./paths": {
46
55
  "types": "./dist/runtime/paths/index.d.ts",
47
56
  "import": "./dist/runtime/paths/index.js"
@@ -111,7 +120,7 @@
111
120
  "react-dom": "^19.2.4",
112
121
  "react-router": "^7.15.1",
113
122
  "tsx": "^4.19.4",
114
- "typescript": "5.9.2",
123
+ "typescript": "7.0.2",
115
124
  "vite": "^8.0.13",
116
125
  "vitest": "^4.1.6",
117
126
  "wrangler": "4.114.0",
package/release.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "source": "npm",
3
- "apiUrl": "https://api.fimo.ai",
4
- "webUrl": "https://fimo.ai"
3
+ "apiUrl": "https://api.staging.fimo.team",
4
+ "webUrl": "https://staging.fimo.team"
5
5
  }
@@ -1,4 +1,5 @@
1
1
  {
2
+ "runtime": { "framework": "react-router" },
2
3
  "seo": {
3
4
  "title": "Welcome to your Fimo website",
4
5
  "description": "A default homepage starter for Fimo projects.",
@@ -9,6 +9,7 @@ dist/
9
9
  build/
10
10
 
11
11
  /.react-router/
12
+ .vercel/
12
13
 
13
14
  # Env
14
15
  .env
@@ -13,7 +13,7 @@
13
13
  "dependencies": {
14
14
  "@base-ui/react": "^1.3.0",
15
15
  "@hookform/resolvers": "^5.5.7",
16
- "@react-router/node": "^8.2.0",
16
+ "@react-router/node": "^8.3.0",
17
17
  "@tailwindcss/typography": "^0.5.19",
18
18
  "@tanstack/react-query": "^5.80.6",
19
19
  "class-variance-authority": "^0.7.1",
@@ -21,7 +21,7 @@
21
21
  "cmdk": "^1.1.1",
22
22
  "date-fns": "^4.1.0",
23
23
  "embla-carousel-react": "^8.6.0",
24
- "fimo": "0.13.0",
24
+ "fimo": "0.14.0-staging.1",
25
25
  "input-otp": "^1.4.2",
26
26
  "isbot": "^5",
27
27
  "lucide-react": "^0.577.0",
@@ -34,7 +34,7 @@
34
34
  "react-error-boundary": "^6.0.0",
35
35
  "react-hook-form": "^7.83.0",
36
36
  "react-resizable-panels": "^4.9.0",
37
- "react-router": "^8.2.0",
37
+ "react-router": "^8.3.0",
38
38
  "recharts": "^3.8.0",
39
39
  "sonner": "^2.0.7",
40
40
  "tailwind-merge": "^3.2.0",
@@ -42,7 +42,7 @@
42
42
  "zod": "^4.4.3"
43
43
  },
44
44
  "devDependencies": {
45
- "@react-router/dev": "^8.2.0",
45
+ "@react-router/dev": "^8.3.0",
46
46
  "@tailwindcss/vite": "^4.3.0",
47
47
  "@types/node": "^24.12.0",
48
48
  "@types/react": "^19.2.14",
@@ -50,7 +50,7 @@
50
50
  "oxlint": "^1.55.0",
51
51
  "tailwindcss": "^4.3.0",
52
52
  "tw-animate-css": "^1.4.0",
53
- "typescript": "5.9.3",
53
+ "typescript": "7.0.2",
54
54
  "vite": "^8.0.13"
55
55
  },
56
56
  "engines": {
@@ -1,8 +1,10 @@
1
1
  import type { Config } from '@react-router/dev/config';
2
+ import { fimoPreset } from 'fimo/react-router/preset';
2
3
 
3
4
  export default {
4
5
  appDirectory: 'src',
5
6
  ssr: false,
7
+ presets: [fimoPreset()],
6
8
  // Static-site generation is opt-in. By default this template builds as an
7
9
  // SPA (single index.html shell, client-side routing). To prerender routes at
8
10
  // build time — required for crawler-visible per-route SEO — add this line:
@@ -22,13 +22,12 @@
22
22
  "noImplicitAny": false,
23
23
 
24
24
  /* Aliases */
25
- "baseUrl": ".",
26
25
  "paths": {
27
- "@/*": ["src/*"],
28
- "@/components/*": ["src/components/*"],
29
- "@/pages/*": ["src/pages/*"],
30
- "@/schemas/*": ["src/schemas/*"],
31
- "@/lib/*": ["src/lib/*"]
26
+ "@/*": ["./src/*"],
27
+ "@/components/*": ["./src/components/*"],
28
+ "@/pages/*": ["./src/pages/*"],
29
+ "@/schemas/*": ["./src/schemas/*"],
30
+ "@/lib/*": ["./src/lib/*"]
32
31
  }
33
32
  },
34
33
  "include": ["src"]