fimo 0.12.0 → 0.12.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 (42) hide show
  1. package/assets/agent-templates/broken-link-sweeper/capabilities.yaml +0 -4
  2. package/assets/agent-templates/content-translator/capabilities.yaml +0 -2
  3. package/assets/agent-templates/seo-audit/capabilities.yaml +0 -1
  4. package/assets/content-templates/types-template.eta +13 -7
  5. package/assets/skills/fimo/SKILL.md +2 -2
  6. package/assets/skills/fimo-cli/SKILL.md +8 -8
  7. package/assets/skills/fimo-cli/references/agent-setup.md +1 -1
  8. package/assets/skills/fimo-cli/references/agents.md +5 -12
  9. package/assets/skills/fimo-cli/references/assets.md +2 -2
  10. package/assets/skills/fimo-cli/references/content.md +16 -30
  11. package/assets/skills/fimo-cli/references/describe.md +1 -1
  12. package/assets/skills/fimo-cli/references/forms.md +8 -8
  13. package/assets/skills/fimo-cli/references/init.md +5 -4
  14. package/assets/skills/fimo-cli/references/labels.md +4 -4
  15. package/assets/skills/fimo-cli/references/locales.md +3 -3
  16. package/assets/skills/fimo-cli/references/project-vars-and-secrets.md +1 -1
  17. package/assets/skills/fimo-code/SKILL.md +40 -50
  18. package/assets/skills/fimo-code/references/assets.md +6 -4
  19. package/assets/skills/fimo-code/references/content/clients.md +130 -0
  20. package/assets/skills/fimo-code/references/content/primitives.md +5 -0
  21. package/assets/skills/fimo-code/references/content/richtext.md +48 -0
  22. package/assets/skills/fimo-code/references/content/schema.md +122 -0
  23. package/assets/skills/fimo-code/references/content.md +12 -597
  24. package/assets/skills/fimo-code/references/design.md +1 -1
  25. package/assets/skills/fimo-code/references/frameworks/next/app-router.md +116 -0
  26. package/assets/skills/fimo-code/references/frameworks/next/locales.md +59 -0
  27. package/assets/skills/fimo-code/references/frameworks/next/pages-router.md +99 -0
  28. package/assets/skills/fimo-code/references/frameworks/next.md +116 -0
  29. package/assets/skills/fimo-code/references/frameworks/react-router.md +295 -0
  30. package/assets/skills/fimo-code/references/frameworks/vite-react.md +225 -0
  31. package/assets/skills/fimo-code/references/labels.md +24 -83
  32. package/assets/skills/fimo-code/references/locales.md +22 -111
  33. package/assets/skills/fimo-code/references/setup-plain-vite.md +3 -227
  34. package/assets/skills/fimo-code/references/setup-react-router.md +3 -276
  35. package/assets/skills/fimo-code/references/ui.md +32 -78
  36. package/dist/cli/bundle.json +2 -2
  37. package/dist/cli/index.js +16 -16
  38. package/dist/scripts/extract-translations.js +8 -1
  39. package/package.json +1 -1
  40. package/templates/react-router/AGENTS.md +10 -10
  41. package/templates/react-router/package.json +1 -1
  42. package/templates/react-router/react-router.config.ts +1 -1
@@ -1,229 +1,5 @@
1
- # Setup Fimo on plain Vite + React
1
+ # Vite + React reference moved
2
2
 
3
- Use this recipe for a Vite + React SPA without React Router framework mode.
4
- This is also the upgrade path for legacy Fimo v3 projects — v3 was plain Vite,
5
- so this layout is what those projects look like now.
3
+ Load `references/frameworks/vite-react.md`.
6
4
 
7
- ## When to use this vs. React Router
8
-
9
- - **Plain Vite (this recipe):** simplest setup; client-side routing via a
10
- React Router library router (`BrowserRouter`, no framework-mode SSR/SSG);
11
- SEO via build-time HTML rewrite. Per-route SEO that crawlers see requires
12
- prerendering (SSG); without it, the SPA serves one `index.html` for every
13
- URL and crawlers see only the home SEO.
14
- - **React Router (`setup-react-router.md`):** framework-mode SSR + per-route
15
- SEO via `meta` export; recommended when you want real per-route crawler SEO.
16
-
17
- ## Prerequisites
18
-
19
- - Node 20+
20
- - A Fimo project created via `fimo init`.
21
-
22
- ## Install
23
-
24
- ```
25
- pnpm add fimo react react-dom react-router @tanstack/react-query
26
- pnpm add -D vite @vitejs/plugin-react @types/react @types/react-dom typescript
27
- ```
28
-
29
- ## File: `package.json`
30
-
31
- ```json
32
- {
33
- "name": "__PROJECT_SLUG__",
34
- "version": "0.0.0",
35
- "private": true,
36
- "type": "module",
37
- "scripts": {
38
- "dev": "vite --host 0.0.0.0 --port 5173",
39
- "build": "vite build",
40
- "preview": "vite preview --host 0.0.0.0 --port 4173",
41
- "typecheck": "tsc --noEmit"
42
- }
43
- }
44
- ```
45
-
46
- Validate runs automatically during `fimo deploy` and API-side sandbox builds.
47
- For a purely local build, run `fimo validate` manually first when you need to
48
- regenerate schemas/forms or check missing labels before `pnpm build`.
49
-
50
- ## File: `vite.config.ts`
51
-
52
- ```ts
53
- import { defineConfig } from 'vite';
54
-
55
- import { fimo } from 'fimo/vite';
56
-
57
- export default defineConfig(() => ({
58
- plugins: fimo({ seo: true }),
59
- }));
60
- ```
61
-
62
- Notes:
63
-
64
- - `fimo({ seo: true })` opts in to the build-time SEO plugin
65
- (`transformIndexHtml`-based). This is the right tool for plain Vite — there's
66
- no framework `meta` export to plug into.
67
- - Add `fimo({ seo: true, sitemap: true, robots: true })` to also emit
68
- `sitemap.xml` and `robots.txt` at build.
69
-
70
- ## File: `index.html`
71
-
72
- ```html
73
- <!doctype html>
74
- <html lang="en">
75
- <head>
76
- <meta charset="UTF-8" />
77
- <meta name="viewport" content="width=device-width, initial-scale=1.0" />
78
- <title>__PROJECT_SLUG__</title>
79
- </head>
80
- <body>
81
- <div id="root"></div>
82
- <script type="module" src="/src/main.tsx"></script>
83
- </body>
84
- </html>
85
- ```
86
-
87
- The `seo` plugin rewrites `<title>`, og, twitter, canonical tags from
88
- `.fimo/config.json#seo` at build time. You can leave a placeholder title in
89
- `index.html`; it'll be replaced.
90
-
91
- ## File: `src/main.tsx`
92
-
93
- `FimoProviders` requires a React Router `<Router>` ancestor (it reads
94
- `useLocation`/`useNavigate`). It reuses a host app's
95
- `@tanstack/react-query` client when one exists and supplies a stable fallback
96
- for adopted SPAs. This recipe still mounts an explicit provider so the app owns
97
- the shared cache and its configuration:
98
-
99
- ```tsx
100
- import { FimoProviders } from 'fimo/react-router';
101
- import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
102
- import React from 'react';
103
- import { createRoot } from 'react-dom/client';
104
- import { BrowserRouter } from 'react-router';
105
-
106
- import { App } from './App';
107
-
108
- const queryClient = new QueryClient();
109
-
110
- createRoot(document.getElementById('root')!).render(
111
- <React.StrictMode>
112
- <QueryClientProvider client={queryClient}>
113
- <BrowserRouter>
114
- <FimoProviders>
115
- <App />
116
- </FimoProviders>
117
- </BrowserRouter>
118
- </QueryClientProvider>
119
- </React.StrictMode>
120
- );
121
- ```
122
-
123
- `react-router` and `@tanstack/react-query` are peer dependencies of `fimo`;
124
- both are in the install command above. `FimoProviders` is exported only from
125
- the `fimo/react-router` adapter barrel. Keep the explicit QueryClientProvider
126
- when the app needs custom query defaults or shared cache access; adopted SPAs
127
- can omit it.
128
-
129
- ## File: `src/App.tsx`
130
-
131
- ```tsx
132
- import { Text, useLabels } from 'fimo/ui';
133
-
134
- export function App() {
135
- const { t } = useLabels();
136
-
137
- return (
138
- <main>
139
- <Text value={t('home.hero.title')} as="h1" />
140
- </main>
141
- );
142
- }
143
- ```
144
-
145
- ## File: `.fimo/config.json`
146
-
147
- ```json
148
- {
149
- "version": "3",
150
- "seo": {
151
- "title": "__PROJECT_SLUG__",
152
- "siteName": "__PROJECT_SLUG__"
153
- },
154
- "routes": {
155
- "home": {
156
- "label": "Home",
157
- "path": "/"
158
- }
159
- }
160
- }
161
- ```
162
-
163
- Note: `"version": "3"` marks the legacy plain-Vite (no-RR-framework-mode)
164
- shape. `fimo()` is version-agnostic — it composes a fixed set of build-time
165
- plugins from the `seo`/`sitemap`/`robots` options you pass and never reads
166
- this version field. It also never injects the React Router plugin: in a
167
- framework-mode project that `reactRouter()` plugin is added by your own
168
- `vite.config.ts`, not by `fimo/vite`.
169
-
170
- ## File: `.fimo/project.json`
171
-
172
- ```json
173
- {
174
- "projectId": "__PROJECT_ID__",
175
- "organizationId": "__ORG_ID__",
176
- "apiUrl": "__API_URL__"
177
- }
178
- ```
179
-
180
- ## File: `tsconfig.json`
181
-
182
- ```json
183
- {
184
- "compilerOptions": {
185
- "target": "ES2022",
186
- "lib": ["DOM", "DOM.Iterable", "ES2022"],
187
- "module": "ESNext",
188
- "moduleResolution": "Bundler",
189
- "jsx": "react-jsx",
190
- "strict": true,
191
- "esModuleInterop": true,
192
- "skipLibCheck": true,
193
- "resolveJsonModule": true,
194
- "isolatedModules": true,
195
- "types": ["vite/client"]
196
- },
197
- "include": ["src", "*.config.ts"]
198
- }
199
- ```
200
-
201
- ## Verify and iterate
202
-
203
- Run the app with the project's package-manager `dev` script (`pnpm dev` /
204
- `npm run dev` / `yarn dev` / `bun dev` — match the lockfile). It serves the site
205
- on localhost with live reload — this is your iteration loop: edit, see the change,
206
- repeat with the developer. `fimo deploy` is on-demand (hosted preview / shareable
207
- link / go live), run only on the developer's signal; the dashboard's preview iframe
208
- shows the **deployed** app, not the localhost dev server.
209
-
210
- ## Known limitations vs. React Router
211
-
212
- - **Per-route SEO that crawlers see** requires either (a) using React Router
213
- framework mode with prerender, (b) a Vite SSG plugin like `vite-plugin-ssg`,
214
- or (c) accepting that the crawler sees the home SEO for every URL.
215
- - **Dashboard "live edit SEO" preview** requires a reload on plain Vite —
216
- there's no React-side head-mutation component yet. The static `seo` plugin
217
- bakes SEO at build time.
218
- - **Routing**: `FimoProviders` requires a React Router context, so this recipe
219
- wires `BrowserRouter` from `react-router`. You can swap it for another
220
- React Router setup (e.g. a `createBrowserRouter` data router with
221
- `<RouterProvider>`), but a `<Router>` ancestor is mandatory — the runtime's
222
- preview bridge and pageview tracker call `useLocation`/`useNavigate`.
223
-
224
- ## What to do next
225
-
226
- - Add a sitemap: pass `fimo({ seo: true, sitemap: true })` and set
227
- `.fimo/config.json#seo.url` to your production base URL.
228
- - Look up exports: see `references/ui.md`.
229
- - Use schema content: see `references/content.md`.
5
+ This compatibility pointer keeps older scaffold comments and agent prompts valid while framework guidance lives in one consistent tree.
@@ -1,278 +1,5 @@
1
- # Setup Fimo on React Router 8
1
+ # React Router reference moved
2
2
 
3
- This recipe describes the canonical Fimo + React Router framework-mode setup.
4
- It mirrors what `fimo init` scaffolds today; you can also apply it to an
5
- existing RR project.
3
+ Load `references/frameworks/react-router.md`.
6
4
 
7
- ## Prerequisites
8
-
9
- - Node 22.22+
10
- - A Fimo project created via `fimo init` (gives you `projectId`,
11
- `organizationId`, and an `apiUrl`).
12
-
13
- ## Install
14
-
15
- ```
16
- pnpm add fimo react react-dom react-router @tanstack/react-query
17
- pnpm add -D @react-router/dev @react-router/node @tailwindcss/vite tailwindcss vite @types/node @types/react @types/react-dom typescript
18
- ```
19
-
20
- ## File: `package.json`
21
-
22
- ```json
23
- {
24
- "name": "__PROJECT_SLUG__",
25
- "version": "0.0.0",
26
- "private": true,
27
- "type": "module",
28
- "scripts": {
29
- "dev": "react-router dev --port 5173",
30
- "build": "react-router build && fimo export-static",
31
- "preview": "vite preview --host 0.0.0.0 --port 4173",
32
- "typecheck": "tsc --noEmit"
33
- }
34
- }
35
- ```
36
-
37
- Validate runs automatically during `fimo deploy` and API-side sandbox builds.
38
- For a purely local build, run `fimo validate` manually first when you need to
39
- regenerate schemas/forms or check missing labels before `pnpm build`.
40
-
41
- ## File: `vite.config.ts`
42
-
43
- ```ts
44
- import { reactRouter } from '@react-router/dev/vite';
45
- import { resolve } from 'path';
46
- import { defineConfig } from 'vite';
47
-
48
- import { fimo } from 'fimo/vite';
49
-
50
- export default defineConfig({
51
- plugins: [reactRouter(), fimo({ sitemap: true })],
52
- resolve: {
53
- alias: {
54
- '@': resolve(__dirname, './src/'),
55
- },
56
- },
57
- });
58
- ```
59
-
60
- Notes:
61
-
62
- - **You** call `reactRouter()`. `fimo/vite` no longer auto-injects it — the
63
- user's vite.config owns the framework plugin. This is the library-mode shape.
64
- - `fimo()` is synchronous; it returns a `PluginOption[]` you drop straight into
65
- `plugins`. Don't `await` it or spread it.
66
- - Do **not** add `fimo({ seo: true })` here. RR handles SEO via the `meta`
67
- export (see `src/root.tsx`); the build-time SEO plugin would conflict.
68
- - `sitemap` is opt-in and off by default; pass `fimo({ sitemap: true })` to emit
69
- `sitemap.xml` (the canonical template does this). Omitting the option leaves
70
- it off.
71
- - `fimo({ robots: true })` opt-in to emit `robots.txt`.
72
-
73
- ## File: `react-router.config.ts`
74
-
75
- ```ts
76
- import type { Config } from '@react-router/dev/config';
77
-
78
- export default {
79
- appDirectory: 'src',
80
- ssr: false,
81
- // Static-site generation is opt-in. By default this template builds as an
82
- // SPA (single index.html shell, client-side routing). To prerender routes at
83
- // build time — required for crawler-visible per-route SEO — add this line:
84
- //
85
- // import { getFimoPaths } from 'fimo/paths';
86
- // prerender: async () => (await getFimoPaths()).map((p) => p.path),
87
- //
88
- // `getFimoPaths()` expands dynamic routes (e.g. `/blog/:slug`) by fetching
89
- // schema entries from the content API. See `references/setup-react-router.md`
90
- // in the fimo skill for the full setup pattern.
91
- buildDirectory: 'dist',
92
- } satisfies Config;
93
- ```
94
-
95
- **SSG is opt-in now.** Default = SPA (one HTML shell). Add `prerender`
96
- yourself if you want crawler-visible per-route HTML. The previous
97
- "prerender everything by default" behavior was a website-builder opinion
98
- that doesn't fit infrastructure mode — your call which routes to prerender,
99
- when to render them, and how.
100
-
101
- ## File: `src/root.tsx`
102
-
103
- The explicit `QueryClientProvider` below is the canonical template shape so the
104
- app can configure query defaults such as `staleTime`. Adopted SPAs can omit it:
105
- `FimoProviders` reuses an ancestor client when present and supplies a stable
106
- fallback otherwise.
107
-
108
- ```tsx
109
- import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
110
- import { FimoProviders, FimoScripts, loadFimoMetaData, buildFimoMeta, fimoHtmlProps } from 'fimo/react-router';
111
- import type { MetaFunction } from 'react-router';
112
- import { Links, Meta, Outlet, Scripts, ScrollRestoration } from 'react-router';
113
-
114
- const queryClient = new QueryClient({
115
- defaultOptions: { queries: { staleTime: Infinity } },
116
- });
117
-
118
- export async function loader(args: { request: Request }) {
119
- return loadFimoMetaData(args);
120
- }
121
-
122
- export const meta: MetaFunction = (args) => buildFimoMeta(args);
123
-
124
- export function Layout({ children }: { children: React.ReactNode }) {
125
- return (
126
- <html {...fimoHtmlProps()}>
127
- <head>
128
- <meta charSet="utf-8" />
129
- <meta name="viewport" content="width=device-width, initial-scale=1" />
130
- <Meta />
131
- <Links />
132
- <FimoScripts />
133
- </head>
134
- <body>
135
- {children}
136
- <ScrollRestoration />
137
- <Scripts />
138
- </body>
139
- </html>
140
- );
141
- }
142
-
143
- export default function AppRoot() {
144
- return (
145
- <QueryClientProvider client={queryClient}>
146
- <FimoProviders>
147
- <Outlet />
148
- </FimoProviders>
149
- </QueryClientProvider>
150
- );
151
- }
152
- ```
153
-
154
- ## File: `src/routes.ts`
155
-
156
- ```ts
157
- import type { RouteConfig } from '@react-router/dev/routes';
158
- import { index } from '@react-router/dev/routes';
159
- import { fimoRoutes } from 'fimo/react-router/routes';
160
-
161
- const routes = [index('./pages/Index.tsx', { id: 'home' })] satisfies RouteConfig;
162
-
163
- export default fimoRoutes(routes) satisfies RouteConfig;
164
- ```
165
-
166
- Page filenames are your choice; the scaffold uses PascalCase (e.g. `Index.tsx`,
167
- `Privacy.tsx`).
168
-
169
- `fimoRoutes()` is Fimo's React Router helper for path-prefix locales. It is a no-op for single-locale projects and expands concrete locale aliases when `.fimo/config.json#i18n.locales` contains more locales. Custom routers can ignore this helper and pass their own locale to `<FimoProviders locale={locale}>`; see `references/locales.md`.
170
-
171
- ## File: `src/pages/Index.tsx`
172
-
173
- ```tsx
174
- import { Text, useLabels } from 'fimo/ui';
175
-
176
- export default function HomePage() {
177
- const { t } = useLabels();
178
-
179
- return (
180
- <main>
181
- <Text value={t('home.hero.title')} as="h1" />
182
- </main>
183
- );
184
- }
185
- ```
186
-
187
- ## File: `.fimo/config.json`
188
-
189
- ```json
190
- {
191
- "version": "4",
192
- "seo": {
193
- "title": "__PROJECT_SLUG__",
194
- "siteName": "__PROJECT_SLUG__"
195
- },
196
- "routes": {
197
- "home": {
198
- "label": "Home",
199
- "path": "/"
200
- }
201
- }
202
- }
203
- ```
204
-
205
- ## File: `.fimo/project.json`
206
-
207
- ```json
208
- {
209
- "projectId": "__PROJECT_ID__",
210
- "organizationId": "__ORG_ID__",
211
- "apiUrl": "__API_URL__"
212
- }
213
- ```
214
-
215
- Replace the `__PROJECT_ID__` / `__ORG_ID__` / `__API_URL__` sentinels with the
216
- values from `fimo init`'s output (or `fimo projects info`).
217
-
218
- ## File: `tsconfig.json`
219
-
220
- ```json
221
- {
222
- "compilerOptions": {
223
- "target": "ES2022",
224
- "lib": ["DOM", "DOM.Iterable", "ES2022"],
225
- "module": "ESNext",
226
- "moduleResolution": "Bundler",
227
- "jsx": "react-jsx",
228
- "strict": true,
229
- "esModuleInterop": true,
230
- "skipLibCheck": true,
231
- "resolveJsonModule": true,
232
- "isolatedModules": true,
233
- "types": ["@react-router/node", "vite/client"],
234
- "paths": { "@/*": ["./src/*"] }
235
- },
236
- "include": ["src", "*.config.ts"]
237
- }
238
- ```
239
-
240
- ## File: `index.css`
241
-
242
- ```css
243
- @import 'tailwindcss';
244
- ```
245
-
246
- (Optional — only if using Tailwind. Tailwind is not required for Fimo to
247
- function; it just ships with the canonical template.)
248
-
249
- ## Verify and iterate
250
-
251
- Run the app with the project's package-manager `dev` script (`pnpm dev` /
252
- `npm run dev` / `yarn dev` / `bun dev` — match the lockfile). It serves the site
253
- on localhost with live reload — this is your iteration loop: edit, see the change,
254
- repeat with the developer.
255
-
256
- `fimo deploy` is on-demand, not part of this loop: run it only when the developer
257
- wants a hosted preview, a shareable link, or to go live — and only on their signal.
258
- The dashboard's preview iframe shows the **deployed** app, so it only reflects
259
- changes after a `fimo deploy` (the local dev server is localhost-only).
260
-
261
- ## What you don't add
262
-
263
- - **No `fimo({ seo: true })`** — React Router's `meta` export covers SEO via
264
- `loadFimoMetaData` + `buildFimoMeta`. The build-time SEO plugin is for
265
- framework-less plain-Vite setups (`setup-vite-plain.md`).
266
- - **No `<FimoSeo />` component** — not part of the RR setup.
267
- - **No manual `<script src="overlay-runtime.js">`** — `<FimoScripts />`
268
- handles preview-script + overlay loading.
269
-
270
- ## What to do next
271
-
272
- - Add more routes: extend `src/routes.ts`, create matching `src/pages/*.tsx`,
273
- add route entries in `.fimo/config.json#routes`.
274
- - Add a sitemap: pass `fimo({ sitemap: true })` (opt-in, off by default; the
275
- canonical template enables it). To customize the base URL, set
276
- `.fimo/config.json#seo.url`.
277
- - Override SEO per route: see `references/seo-overrides.md`.
278
- - Look up an export: see `references/api.md`.
5
+ This compatibility pointer keeps older scaffold comments and agent prompts valid while framework guidance lives in one consistent tree.
@@ -1,90 +1,44 @@
1
- # UI: components, JSX conventions, code rules
1
+ # React rendering primitives
2
2
 
3
- Everything about writing React code in a Fimo project: the `fimo/ui` component set, app code conventions (routing, components, loading states), and the JSX-side anti-patterns.
3
+ Use Fimo components for source-tracked schema and label values so Studio can identify the field being rendered. Generated reads wrap editable fields with source metadata; pass the whole value to the matching primitive because unwrapping it first removes Studio's edit target.
4
4
 
5
- Load this for **any JSX work** that renders schema content, `t()` output, or media — and any time you're creating components, pages, or routes.
5
+ | Schema/read value | Component | Use |
6
+ | -------------------------------- | ------------- | ----------------------------------------- |
7
+ | string/text/date as `FimoString` | `Text` | editable text and `t()` values |
8
+ | richtext as `FimoRichText` | `RichText` | Tiptap JSONContent |
9
+ | media as `FimoMedia` | `Image` | schema media images |
10
+ | non-schema URL | `StaticImage` | decorative/static image URLs |
11
+ | media as `FimoMedia` | `Video` | schema media videos |
12
+ | date as `FimoString` | `Date` | schema dates |
13
+ | boolean as `FimoBoolean` | `Boolean` | schema booleans |
14
+ | source-tagged plain JSON | `Json` | schema JSON |
15
+ | number | normal JSX | numbers stay plain; no `Number` primitive |
16
+ | reference | target fields | populate before rendering |
17
+ | blocks | nested fields | render each value with its primitive |
6
18
 
7
- ## `fimo/ui` components
19
+ ```tsx
20
+ <Text value={article.title} as="h1" />
21
+ <RichText value={article.body} />
22
+ <Image value={article.cover} width={1200} height={630} />
23
+ <Date value={article.publishedAt} />
24
+ ```
8
25
 
9
- Use these to render content-type field values consistently. They carry source metadata for inline editing in the Fimo admin — **always prefer them over raw HTML** when the value comes from a schema or `t()`.
26
+ Pass the tracked value directly. Do not replace `<Text>` with `<h1>{article.title}</h1>`, unwrap media into raw `<img>`, or hand-roll richtext rendering.
10
27
 
11
- | Component | Use for | Example |
12
- | --------------- | ------------------------------------------------------------------- | ------------------------------------------------------------- |
13
- | `<Text>` | Schema text fields + `t()` output | `<Text value={post.title} as="h1" />` |
14
- | `<RichText>` | Schema `richtext` fields (Tiptap JSONContent) | `<RichText value={post.body} className="prose" />` |
15
- | `<Image>` | Schema `media` image fields | `<Image value={post.coverImage} width={1200} height={630} />` |
16
- | `<StaticImage>` | Non-schema images (hard-coded decorative imagery, hero backgrounds) | `<StaticImage src="/hero.jpg" alt="..." width={1200} />` |
17
- | `<Video>` | Schema `media` video fields | `<Video value={post.heroVideo} />` |
18
- | `<Date>` | Schema date fields | `<Date value={post.publishDate} />` |
19
- | `<Boolean>` | Schema boolean fields | `<Boolean value={product.inStock} />` |
20
- | `<Json>` | Schema `json` fields | `<Json value={post.metadata} as="pre" />` |
21
- | `` fimo`...` `` | Compose tracked values (mix `t()` + schema text) | ``<Text value={fimo`${t('by')} ${post.author}`} />`` |
22
- | `useLabels()` | `t('key')` hook | see `references/labels.md` |
23
- | `useLocale()` | Active locale and route locale metadata | see `references/locales.md` |
28
+ Use `<StaticImage>` only when the image is deliberately not editor-managed. Use `String(value)` for attributes/third-party APIs that cannot accept a `FimoString`; keep editable visible text in `<Text>`.
24
29
 
25
- ### Rules of thumb
30
+ Never construct `FimoString`, `FimoRichText`, `FimoBoolean`, or `FimoMedia` manually. Generated clients and label readers attach the correct source path.
26
31
 
27
- 1. **Schema text → `<Text>`**, never `<h1>{post.title}</h1>`.
28
- 2. **Schema media → `<Image>` / `<Video>`**, never `<img src={post.coverImage.url} />`. Provide `width` / `height` when known so Fimo can optimize and reserve layout space.
29
- 3. **Non-schema images** (decorative, hard-coded URLs, generated assets referenced directly) → `<StaticImage>`. Never hand-construct a `FimoMedia` to feed `<Image>`.
30
- 4. **Label text → `<Text value={t('key')} />`**, not `<h1>{t(...)}</h1>`. Label values live in the DB for `i18n.defaultLocale` from `.fimo/config.json` unless a non-default locale is explicitly targeted. See `references/labels.md`.
31
- 5. **Mixed schema + translated text** → the `` fimo`...` `` template literal inside `<Text>`.
32
- 6. **Never hand-roll richtext rendering** — always `<RichText>`. To restyle a node, pass `components={{ heading: ..., link: ..., ... }}`.
33
- 7. **Schema `json` → `<Json>`**, not a hand-rolled `<pre data-fimo-source={getFimoSource(post.metadata)}>{JSON.stringify(post.metadata)}</pre>`. Default renders as a `<span>`; pass `as="pre"` (with a `whitespace-pre-wrap` class) for a formatted block, or a children render function for custom display of specific keys.
32
+ ## Imports
34
33
 
35
- ## App code conventions
34
+ Choose the framework surface:
36
35
 
37
- The template uses **Vite + React 19 + TypeScript + Tailwind v4 + shadcn/ui + react-router**. Keep generated code consistent.
36
+ - Next Server Components and data functions → `fimo/next`
37
+ - Next Client Components → `fimo/next/client`
38
+ - React Router/Vite client → `fimo/ui`
38
39
 
39
- ### Component structure
40
+ Load the framework reference before copying an example. Next server and client imports are deliberately separate so React Query/client code does not leak into server bundles.
40
41
 
41
- - Components small and focused (< 50 lines where possible). Place page-specific components under `src/components/[pageName]/`; shared ones under `src/components/shared/`.
42
- - Use shadcn/ui primitives from `src/components/ui/` rather than rolling your own.
43
- - Split files when they grow past ~300 lines.
42
+ ## Component ownership
44
43
 
45
- ### Routing
46
-
47
- - This template uses React Router 8 framework mode (file-based route config in `src/routes.ts`). Use `<FimoLink>` from `fimo/react-router` for locale-aware internal links, especially in projects with more than one configured locale. Use React Router `<Link>` / `<NavLink>` only when you intentionally do not want Fimo's locale behavior. Never raw `<a href="/...">` for internal navigation because it causes full page reloads.
48
- - Reserve `<a>` for external links, with `target="_blank" rel="noreferrer"`.
49
-
50
- ### Loading states
51
-
52
- - Skeletons > spinners > text placeholders. Never render the literal string "Loading…".
53
- - Render a skeleton approximating the final layout (title bar, text lines, media aspect box).
54
- - For images, reserve the aspect ratio with a skeleton — never a placeholder image. Layout must not jump.
55
-
56
- ### Tailwind v4
57
-
58
- - Use utility classes with `cn()` from `@/lib/utils` for conditional classes.
59
- - Prefer flexbox for 1D layouts and grid for 2D layouts; avoid floats and absolute positioning.
60
- - Theme via shadcn CSS variables in `src/index.css` (`--background`, `--foreground`, `--primary`, `--accent`, `--ring`, etc.). Use semantic Tailwind classes (`bg-background`, `text-foreground`, `bg-primary`) instead of raw colors so light/dark stays coherent.
61
- - Tailwind v4 syntax (e.g., `size-*`, container queries) — don't assume v3 conventions.
62
-
63
- ### Starter replacement
64
-
65
- - `src/pages/Index.tsx` is disposable scaffold so a fresh `fimo init` project renders immediately.
66
- - **On the first real website generation, replace that starter page's copy, layout, and visual system entirely** instead of decorating the existing Fimo-branded design.
67
- - Reuse only the app shell, route contracts, and legal pages unless the user explicitly wants the starter aesthetic.
68
-
69
- ### Legal pages
70
-
71
- - `src/pages/Privacy.tsx` and `src/pages/Terms.tsx` ship with the template but are not yet wired in `src/routes.ts` — add `route('privacy', './pages/Privacy.tsx')` and `route('terms', './pages/Terms.tsx')` when building a public site. They are required for public sites.
72
- - Adapt their styling to match the project's visual language and translate their copy via `t()`.
73
- - Use `privacy@fimo.ai` as the default legal contact email unless the user provides one.
74
-
75
- ### Branding
76
-
77
- - **No Fimo branding** in the generated user-facing site unless the user explicitly asks for it.
78
-
79
- ## Anti-patterns (JSX-side)
80
-
81
- - Raw `<a href>` for internal nav → use `<FimoLink>` for locale-aware paths or React Router `<Link>` / `<NavLink>` only when intentionally bypassing Fimo locale helpers.
82
- - Raw `<img>` for schema media → use `<Image>` (with width/height).
83
- - Raw `<pre data-fimo-source={getFimoSource(...)}>` for schema `json` fields → use `<Json>`.
84
- - Hardcoded strings in JSX → wrap in `t('key')` and add the DB value with `fimo labels set`.
85
- - Calling `t()` with a dynamic first argument → key must be a string literal.
86
- - Editing generated `.ts` files under `src/schemas/` or `src/forms/` → regenerate them through `fimo validate` or the matching push command.
87
- - Writing raw HTML into a `richtext` field → must be Tiptap JSONContent.
88
- - Hand-constructing a `FimoMedia` object to pass into `<Image>` → use `<StaticImage>` for non-schema images.
89
- - Decorating `src/pages/Index.tsx` → replace it on first real generation.
90
- - "Loading…" text placeholder → render a skeleton matching the final layout.
44
+ Fimo does not prescribe component folders, styling, routing, loading UI, or design system. Preserve the application's existing conventions. Use skeletons or its established loading surface for client queries; do not introduce a new UI kit merely to render Fimo values.
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "bundled": true,
3
3
  "bundler": "esbuild",
4
- "bundledAt": "2026-08-11T09:16:53.645Z",
5
- "cliVersion": "0.12.0",
4
+ "bundledAt": "2026-08-11T13:10:15.212Z",
5
+ "cliVersion": "0.12.1",
6
6
  "external": [
7
7
  "oxc-parser",
8
8
  "fsevents",