Skip to content

Commit d2b05c5

Browse files
V VV V
authored andcommitted
docs: restructure into coherent chapter flow with proper chapters and navigation
1 parent c558ca4 commit d2b05c5

27 files changed

Lines changed: 798 additions & 6079 deletions

DEVELOPER_GUIDE.md

Lines changed: 26 additions & 402 deletions
Large diffs are not rendered by default.

apps/docs/content/app-development.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -626,7 +626,7 @@ Data sources are fetched server-side and injected as props:
626626
}
627627
```
628628

629-
Routes listed in `prerender` are pre-rendered to static HTML at deploy time and served directly from disk. All other routes render dynamically as normal. Use `/*` globs to pre-render all content under a prefix (e.g., `"/blog/*"` pre-renders every blog post). See [Hybrid Pre-render](/hybrid-prerender) for details.
629+
Routes listed in `prerender` are pre-rendered to static HTML at deploy time and served directly from disk. All other routes render dynamically as normal. Use `/*` globs to pre-render all content under a prefix (e.g., `"/blog/*"` pre-renders every blog post). See [Deployment](/deployment) for details.
630630

631631
### With Actions (API forwarding)
632632

@@ -837,3 +837,7 @@ import { Head, Link } from '@magneticjs/server/jsx-runtime'; // ✅
837837
| Rendering | Server renders → DOM snapshot → SSE push | Client React → virtual DOM → reconcile |
838838
| Bundle size | ~2KB client + 0 framework JS | 80-150KB+ |
839839
| Hydration | None (no client framework) | Required (framework bootstrap) |
840+
841+
---
842+
843+
← [Previous: Getting Started](/getting-started) · **Chapter 2** · [Next: Component Patterns →](/components)

apps/docs/content/benchmarks.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
title: Benchmarks
33
description: Performance measurements vs Next.js, Remix, HTMX, and other frameworks.
44
layout: docs
5-
order: 5
5+
order: 6
66
---
77

88
# Magnetic Performance Benchmarks
@@ -118,3 +118,7 @@ The same server powers all platforms:
118118
| Native mobile | **Built-in** | None (separate codebase) |
119119

120120
Magnetic's structural advantage: the server renders everything, the client is a thin patcher. This inverts the typical SPA model where the client does all the work.
121+
122+
---
123+
124+
[Previous: Deployment](/deployment) · **Chapter 6** · End of docs

apps/docs/content/components.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -510,3 +510,7 @@ Components only need to import from `@magneticjs/server/jsx-runtime`. The CSS fr
510510
- [App Development Reference](/app-development) — Pages, state, actions, data sources
511511
- [CSS & Styling](/css-styling) — Design tokens, utility classes, custom CSS
512512
- [GitHub: Example apps](https://github.com/inventhq/magnetic/tree/main/apps) — Real app examples
513+
514+
---
515+
516+
← [Previous: App Development](/app-development) · **Chapter 3** · [Next: CSS & Styling →](/css-styling)

apps/docs/content/css-styling.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -772,3 +772,7 @@ If you need to verify a class name or understand how something works:
772772
| `apps/task-board/public/style.css` | Real-world custom CSS example (23 lines) |
773773
| `apps/task-board/pages/TasksPage.tsx` | Utility classes in use |
774774
| `apps/task-board/components/TaskCard.tsx` | Dynamic classes from toViewModel |
775+
776+
---
777+
778+
← [Previous: Component Patterns](/components) · **Chapter 4** · [Next: Deployment →](/deployment)

apps/docs/content/deployment.md

Lines changed: 235 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,235 @@
1+
---
2+
title: Deployment
3+
description: Deploy Magnetic apps — SSR, static site generation, and hybrid pre-render.
4+
layout: docs
5+
order: 5
6+
---
7+
8+
# Deployment
9+
10+
Magnetic supports three deployment modes. Choose based on your app's needs:
11+
12+
| Mode | Command | Use case | Server required |
13+
|------|---------|----------|-----------------|
14+
| **SSR** | `magnetic push` | Dynamic apps with real-time data, user sessions | Yes |
15+
| **Hybrid** | `magnetic push` + `prerender` in config | Mix of static content + live interactive pages | Yes |
16+
| **SSG** | `magnetic push --static` | Docs, blogs, marketing pages — zero JS | No |
17+
18+
## SSR Deployment
19+
20+
The default. Your app is rendered on demand for every request with full interactivity — actions, SSE, real-time data, user sessions.
21+
22+
```bash
23+
# Build and deploy in one command
24+
magnetic push --name my-app --server https://api.fujs.dev
25+
26+
# Or specify a directory
27+
magnetic push --dir apps/my-app --name my-app --server https://api.fujs.dev
28+
```
29+
30+
Your app gets a subdomain: `https://my-app.fujs.dev`
31+
32+
What gets deployed: your pages, components, state, config, and static assets. One command, no Docker, no CI pipeline. Deploys hot-reload instantly.
33+
34+
## Static Site Generation (SSG)
35+
36+
Pre-renders your pages to **pure static HTML** at build time. No JavaScript, no SSE, no server required. Deploy to the Magnetic platform or any static host.
37+
38+
```bash
39+
# Build and deploy static site
40+
magnetic push --static --name my-app --server https://api.fujs.dev
41+
42+
# Or build only (outputs to dist/)
43+
magnetic build --static
44+
```
45+
46+
SSG is the right choice when your content doesn't change per-request. The same `content/*.md` files and page components work in both modes — the only difference is the output.
47+
48+
### How SSG Works
49+
50+
1. **Build**: The CLI bundles your app (pages, state, JSX runtime, CSS framework) into `app.js`
51+
2. **Render**: Each route is rendered through the same server pipeline used for SSR
52+
3. **Extract**: `<Head>` components become `<head>` elements, design tokens become inlined `<style>`
53+
4. **Write**: Each page is written as `{route}/index.html`
54+
55+
Each route produces a self-contained HTML file with inlined CSS. Navigation uses plain `<a href>` links — standard browser navigation, no JavaScript needed.
56+
57+
### Content Pipeline
58+
59+
SSG works with the `content/` folder — the same markdown files used in SSR mode:
60+
61+
```
62+
my-app/
63+
content/
64+
getting-started.md
65+
components.md
66+
api-reference.md
67+
pages/
68+
IndexPage.tsx
69+
[slug].tsx ← dynamic route for /:slug
70+
server/
71+
state.ts
72+
magnetic.json
73+
design.json
74+
```
75+
76+
Each `.md` file with frontmatter becomes a route:
77+
78+
```markdown
79+
---
80+
title: Getting Started
81+
description: Build your first Magnetic app
82+
order: 1
83+
---
84+
85+
# Getting Started
86+
87+
Your markdown content here...
88+
```
89+
90+
### Lazy Content Mode
91+
92+
For sites with hundreds or thousands of pages, baking all content into the JS bundle is wasteful. **Lazy content mode** keeps only the metadata index in the bundle and loads each `.md` file on demand during SSG:
93+
94+
```bash
95+
# Default: all content baked into bundle (~161KB for 5 pages)
96+
magnetic build --static
97+
98+
# Lazy: metadata index only, .md loaded on demand (~30KB bundle)
99+
magnetic build --static --lazy-content
100+
```
101+
102+
#### Performance at Scale
103+
104+
| Pages | Bundle mode | Lazy mode |
105+
|-------|------------|-----------|
106+
| 5 | 161KB bundle, 8ms render | 30KB bundle, 8ms render |
107+
| 100 | ~500KB bundle | 30KB bundle |
108+
| 1,000 | ~5MB bundle | 30KB bundle |
109+
| 10,000 | impractical | **30KB bundle, ~15s total** |
110+
111+
Benchmark (M1 MacBook Air): **10,006 pages in ~15 seconds** (1.5ms per page). The bundle stays at 30KB regardless of content count.
112+
113+
The key advantage: **adding a new `.md` file requires zero rebuild** in lazy mode. The bundle never changes — only the SSG output step runs.
114+
115+
### Deploy SSG to External Hosts
116+
117+
The `dist/` directory is deployable to any static host:
118+
119+
```bash
120+
# Netlify
121+
netlify deploy --dir=dist --prod
122+
123+
# Cloudflare Pages
124+
npx wrangler pages deploy dist
125+
126+
# GitHub Pages
127+
# Copy dist/ to your gh-pages branch
128+
129+
# Any static server
130+
npx http-server dist -p 3000
131+
```
132+
133+
## Hybrid Pre-render
134+
135+
For apps that mix static content and dynamic pages — like a news site with blog posts AND live dashboards — you can **pre-render specific routes** at deploy time while keeping the rest fully dynamic.
136+
137+
Pre-rendered pages are served instantly from disk. Everything else renders on demand with full interactivity.
138+
139+
### Configuration
140+
141+
Add a `prerender` array to `magnetic.json`:
142+
143+
```json
144+
{
145+
"name": "my-app",
146+
"prerender": ["/", "/about", "/blog/*"]
147+
}
148+
```
149+
150+
When you run `magnetic push`, the CLI:
151+
1. Builds the SSR bundle as normal
152+
2. Pre-renders the listed routes to static HTML
153+
3. Deploys both the bundle AND the pre-rendered pages
154+
155+
The platform checks for a pre-rendered file first. If one exists, it's served instantly. If not, the server renders on demand as usual.
156+
157+
### Glob Patterns
158+
159+
Use `/*` to pre-render all content under a prefix:
160+
161+
| Pattern | Expands to |
162+
|---------|-----------|
163+
| `"/"` | Just the homepage |
164+
| `"/about"` | Single route |
165+
| `"/blog/*"` | All content slugs under `blog/` |
166+
| `"/docs/*"` | All content slugs under `docs/` |
167+
168+
Globs expand against your `content/` directory slugs and static page routes. Dynamic routes (`:param`) and catch-all routes are skipped.
169+
170+
### Example: News Site
171+
172+
```json
173+
{
174+
"name": "my-news-site",
175+
"server": "https://api.fujs.dev",
176+
"prerender": ["/", "/about", "/articles/*", "/categories/*"],
177+
"data": {
178+
"live-feed": {
179+
"url": "https://api.example.com/live",
180+
"type": "sse",
181+
"page": "/live"
182+
}
183+
}
184+
}
185+
```
186+
187+
| Route | Behavior |
188+
|-------|----------|
189+
| `/`, `/about` | Served as static HTML (instant, no compute) |
190+
| `/articles/*`, `/categories/*` | Pre-rendered from `content/` markdown (instant) |
191+
| `/live` | Rendered on demand with real-time SSE updates (dynamic) |
192+
193+
### Content Updates
194+
195+
Pre-rendered pages are generated at **deploy time**. To update content:
196+
197+
1. Edit your `content/*.md` files
198+
2. Run `magnetic push` again
199+
3. The CLI re-renders all pre-render routes with the new content
200+
201+
The pre-render step adds only milliseconds to the deploy process.
202+
203+
## Navigation Across Modes
204+
205+
| Mode | Navigation behavior |
206+
|------|-------------------|
207+
| **SSR** | `<Link>` uses client-side navigation — no full page reload |
208+
| **SSG** | Plain `<a href>` links — standard browser navigation, zero JS |
209+
| **Hybrid** | Pre-rendered pages use `<a href>`, dynamic pages use client-side navigation |
210+
211+
Your page components work identically in all modes. The `href` attribute on `<Link>` and `<a>` is what matters.
212+
213+
## Choosing a Mode
214+
215+
### Choose SSR when:
216+
- Every page needs dynamic rendering
217+
- You have few pages and server compute is negligible
218+
- All pages use real-time data or user-specific content
219+
220+
### Choose Hybrid when:
221+
- Your site has hundreds or thousands of content pages (blog posts, docs, articles)
222+
- Some pages need real-time data, user sessions, or interactivity
223+
- You want content pages to load instantly without server compute
224+
- You want to deploy everything as a single app
225+
226+
### Choose SSG when:
227+
- Every page is static (docs site, marketing site, blog)
228+
- You don't need any server-side interactivity
229+
- You want zero server cost
230+
231+
The `content/` folder is the single source of truth in all modes — same markdown files, same `getContent()`/`listContent()` API, same page components. Only the serving behavior differs.
232+
233+
---
234+
235+
[Previous: CSS & Styling](/css-styling) · **Chapter 5** · [Next: Benchmarks →](/benchmarks)

apps/docs/content/getting-started.md

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -423,8 +423,11 @@ import { Head, Link } from '@magneticjs/server/jsx-runtime';
423423
- [Component Patterns](/components) — Building reusable components
424424
- [CSS & Styling](/css-styling) — Design tokens, utility classes, custom CSS
425425
- [Benchmarks](/benchmarks) — Performance measurements vs other frameworks
426-
- [Static Site Generation](/static-site-generation) — SSG, lazy content, deployment
427-
- [Hybrid Pre-render](/hybrid-prerender) — Mix static + dynamic pages in one app
426+
- [Deployment](/deployment) — SSR deploy, SSG, hybrid pre-render
428427
- [npm: @magneticjs/cli](https://www.npmjs.com/package/@magneticjs/cli) — CLI package
429428
- [npm: @magneticjs/server](https://www.npmjs.com/package/@magneticjs/server) — JSX runtime
430429
- [GitHub](https://github.com/inventhq/magnetic) — Source code
430+
431+
---
432+
433+
← [Previous: Introduction](/introduction) · **Chapter 1** · [Next: App Development →](/app-development)

0 commit comments

Comments
 (0)