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.
- package/assets/agent-templates/broken-link-sweeper/capabilities.yaml +0 -4
- package/assets/agent-templates/content-translator/capabilities.yaml +0 -2
- package/assets/agent-templates/seo-audit/capabilities.yaml +0 -1
- package/assets/content-templates/types-template.eta +13 -7
- package/assets/skills/fimo/SKILL.md +2 -2
- package/assets/skills/fimo-cli/SKILL.md +8 -8
- package/assets/skills/fimo-cli/references/agent-setup.md +1 -1
- package/assets/skills/fimo-cli/references/agents.md +5 -12
- package/assets/skills/fimo-cli/references/assets.md +2 -2
- package/assets/skills/fimo-cli/references/content.md +16 -30
- package/assets/skills/fimo-cli/references/describe.md +1 -1
- package/assets/skills/fimo-cli/references/forms.md +8 -8
- package/assets/skills/fimo-cli/references/init.md +5 -4
- package/assets/skills/fimo-cli/references/labels.md +4 -4
- package/assets/skills/fimo-cli/references/locales.md +3 -3
- package/assets/skills/fimo-cli/references/project-vars-and-secrets.md +1 -1
- package/assets/skills/fimo-code/SKILL.md +40 -50
- package/assets/skills/fimo-code/references/assets.md +6 -4
- package/assets/skills/fimo-code/references/content/clients.md +130 -0
- package/assets/skills/fimo-code/references/content/primitives.md +5 -0
- package/assets/skills/fimo-code/references/content/richtext.md +48 -0
- package/assets/skills/fimo-code/references/content/schema.md +122 -0
- package/assets/skills/fimo-code/references/content.md +12 -597
- package/assets/skills/fimo-code/references/design.md +1 -1
- package/assets/skills/fimo-code/references/frameworks/next/app-router.md +116 -0
- package/assets/skills/fimo-code/references/frameworks/next/locales.md +59 -0
- package/assets/skills/fimo-code/references/frameworks/next/pages-router.md +99 -0
- package/assets/skills/fimo-code/references/frameworks/next.md +116 -0
- package/assets/skills/fimo-code/references/frameworks/react-router.md +295 -0
- package/assets/skills/fimo-code/references/frameworks/vite-react.md +225 -0
- package/assets/skills/fimo-code/references/labels.md +24 -83
- package/assets/skills/fimo-code/references/locales.md +22 -111
- package/assets/skills/fimo-code/references/setup-plain-vite.md +3 -227
- package/assets/skills/fimo-code/references/setup-react-router.md +3 -276
- package/assets/skills/fimo-code/references/ui.md +32 -78
- package/dist/cli/bundle.json +2 -2
- package/dist/cli/index.js +16 -16
- package/dist/scripts/extract-translations.js +8 -1
- package/package.json +1 -1
- package/templates/react-router/AGENTS.md +10 -10
- package/templates/react-router/package.json +1 -1
- package/templates/react-router/react-router.config.ts +1 -1
|
@@ -1,229 +1,5 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Vite + React reference moved
|
|
2
2
|
|
|
3
|
-
|
|
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
|
-
|
|
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
|
-
#
|
|
1
|
+
# React Router reference moved
|
|
2
2
|
|
|
3
|
-
|
|
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
|
-
|
|
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
|
-
#
|
|
1
|
+
# React rendering primitives
|
|
2
2
|
|
|
3
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
30
|
+
Never construct `FimoString`, `FimoRichText`, `FimoBoolean`, or `FimoMedia` manually. Generated clients and label readers attach the correct source path.
|
|
26
31
|
|
|
27
|
-
|
|
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
|
-
|
|
34
|
+
Choose the framework surface:
|
|
36
35
|
|
|
37
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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.
|
package/dist/cli/bundle.json
CHANGED