@timber-js/app 0.2.0-alpha.196 → 0.2.0-alpha.198
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/dist/_chunks/{actions-CWYtq6ii.js → actions-BS-m5SLv.js} +3 -3
- package/dist/_chunks/{actions-CWYtq6ii.js.map → actions-BS-m5SLv.js.map} +1 -1
- package/dist/_chunks/als-registry-C6kcfprT.js.map +1 -1
- package/dist/_chunks/{build-manifest-DWppEdLB.js → build-manifest-DTmSGLRz.js} +51 -2
- package/dist/_chunks/build-manifest-DTmSGLRz.js.map +1 -0
- package/dist/_chunks/{cache-api-CQeYzA5g.js → cache-api-DqzgTEqk.js} +4 -49
- package/dist/_chunks/cache-api-DqzgTEqk.js.map +1 -0
- package/dist/_chunks/{chains-h7EO-u3n.js → chains-CZG7E5zg.js} +2 -2
- package/dist/_chunks/{chains-h7EO-u3n.js.map → chains-CZG7E5zg.js.map} +1 -1
- package/dist/_chunks/{cli-check-BVthpfLS.js → cli-check-dVDi1GQz.js} +3 -3
- package/dist/_chunks/{cli-check-BVthpfLS.js.map → cli-check-dVDi1GQz.js.map} +1 -1
- package/dist/_chunks/{cli-schema-sync-3Wutm8pH.js → cli-schema-sync-DTy_-Msq.js} +2 -2
- package/dist/_chunks/{cli-schema-sync-3Wutm8pH.js.map → cli-schema-sync-DTy_-Msq.js.map} +1 -1
- package/dist/_chunks/{cloudflare-BKJC3SC_.js → cloudflare-BFb__LYG.js} +2 -2
- package/dist/_chunks/{cloudflare-BKJC3SC_.js.map → cloudflare-BFb__LYG.js.map} +1 -1
- package/dist/_chunks/{convention-lint-DO10_pVl.js → convention-lint-Ph6luW4c.js} +4 -2
- package/dist/_chunks/convention-lint-Ph6luW4c.js.map +1 -0
- package/dist/_chunks/{error-boundary-D-lkwyaD.js → error-boundary-BvRCCmbN.js} +3 -3
- package/dist/_chunks/{error-boundary-D-lkwyaD.js.map → error-boundary-BvRCCmbN.js.map} +1 -1
- package/dist/_chunks/{href-validation-CMc5JRls.js → href-validation-BIrxavIy.js} +74 -2
- package/dist/_chunks/href-validation-BIrxavIy.js.map +1 -0
- package/dist/_chunks/{live-graph-Bx4HodF1.js → live-graph-BXDsdzBv.js} +3 -3
- package/dist/_chunks/{live-graph-Bx4HodF1.js.map → live-graph-BXDsdzBv.js.map} +1 -1
- package/dist/_chunks/{logger-pumCm3Il.js → logger-DDirEsn7.js} +3 -4
- package/dist/_chunks/{logger-pumCm3Il.js.map → logger-DDirEsn7.js.map} +1 -1
- package/dist/_chunks/navigation-root-B00jjGd5.js +233 -0
- package/dist/_chunks/navigation-root-B00jjGd5.js.map +1 -0
- package/dist/_chunks/{segment-context-CjOlyB8Y.js → param-value-C8TNYchQ.js} +2 -33
- package/dist/_chunks/param-value-C8TNYchQ.js.map +1 -0
- package/dist/_chunks/{poison-scan-BAxfTT5L.js → poison-scan-BoDLgbix.js} +2 -2
- package/dist/_chunks/{poison-scan-BAxfTT5L.js.map → poison-scan-BoDLgbix.js.map} +1 -1
- package/dist/_chunks/{router-ref-BzqbPwYC.js → router-ref-8gr8qsxN.js} +2 -2
- package/dist/_chunks/{router-ref-BzqbPwYC.js.map → router-ref-8gr8qsxN.js.map} +1 -1
- package/dist/_chunks/{rsc-cache-key-DD0fl_-s.js → rsc-cache-key-ClUiXQnK.js} +2 -2
- package/dist/_chunks/{rsc-cache-key-DD0fl_-s.js.map → rsc-cache-key-ClUiXQnK.js.map} +1 -1
- package/dist/_chunks/{scanner-BRIOmHE2.js → scanner-tdFPvDYi.js} +174 -7
- package/dist/_chunks/scanner-tdFPvDYi.js.map +1 -0
- package/dist/_chunks/segment-context-D9_89u34.js +34 -0
- package/dist/_chunks/segment-context-D9_89u34.js.map +1 -0
- package/dist/_chunks/singleflight-2lUWfcAk.js +54 -0
- package/dist/_chunks/singleflight-2lUWfcAk.js.map +1 -0
- package/dist/_chunks/{ssr-data-Ya2HJPFp.js → ssr-data-BQGhTPAK.js} +2 -17
- package/dist/_chunks/ssr-data-BQGhTPAK.js.map +1 -0
- package/dist/_chunks/{walkers-BU6z9xRV.js → walkers-DNX05dC0.js} +2 -2
- package/dist/_chunks/{walkers-BU6z9xRV.js.map → walkers-DNX05dC0.js.map} +1 -1
- package/dist/adapters/cloudflare-dev.js +1 -1
- package/dist/adapters/cloudflare-kv-cache.js +1 -1
- package/dist/adapters/cloudflare.js +1 -1
- package/dist/adapters/nitro.d.ts +1 -1
- package/dist/adapters/nitro.d.ts.map +1 -1
- package/dist/adapters/nitro.js.map +1 -1
- package/dist/analyze/crawl-entry.js +2 -2
- package/dist/analyze/graph-command.js +2 -2
- package/dist/cache/index.js +1 -1
- package/dist/cache/singleflight.d.ts +2 -0
- package/dist/cache/singleflight.d.ts.map +1 -1
- package/dist/cli.js +2 -2
- package/dist/client/browser-entry/hydrate.d.ts +21 -15
- package/dist/client/browser-entry/hydrate.d.ts.map +1 -1
- package/dist/client/browser-entry/index.d.ts +4 -3
- package/dist/client/browser-entry/index.d.ts.map +1 -1
- package/dist/client/browser-entry/post-hydration.d.ts.map +1 -1
- package/dist/client/browser-entry/router-init.d.ts +17 -1
- package/dist/client/browser-entry/router-init.d.ts.map +1 -1
- package/dist/client/error-boundary.js +1 -1
- package/dist/client/global-context.d.ts +15 -0
- package/dist/client/global-context.d.ts.map +1 -0
- package/dist/client/index.js +138 -35
- package/dist/client/index.js.map +1 -1
- package/dist/client/internal.d.ts +0 -1
- package/dist/client/internal.d.ts.map +1 -1
- package/dist/client/internal.js +206 -55
- package/dist/client/internal.js.map +1 -1
- package/dist/client/link.d.ts.map +1 -1
- package/dist/client/location-search.d.ts +12 -0
- package/dist/client/location-search.d.ts.map +1 -0
- package/dist/client/navigation-api.d.ts.map +1 -1
- package/dist/client/navigation-commit.d.ts +18 -0
- package/dist/client/navigation-commit.d.ts.map +1 -1
- package/dist/client/navigation-context.d.ts +13 -11
- package/dist/client/navigation-context.d.ts.map +1 -1
- package/dist/client/navigation-root.d.ts +47 -108
- package/dist/client/navigation-root.d.ts.map +1 -1
- package/dist/client/navigation-transition.d.ts +136 -0
- package/dist/client/navigation-transition.d.ts.map +1 -0
- package/dist/client/nuqs-adapter.d.ts.map +1 -1
- package/dist/client/params-context.d.ts +4 -5
- package/dist/client/params-context.d.ts.map +1 -1
- package/dist/client/react-root.d.ts +44 -0
- package/dist/client/react-root.d.ts.map +1 -0
- package/dist/client/router-pipeline.d.ts +2 -2
- package/dist/client/router-pipeline.d.ts.map +1 -1
- package/dist/client/router-types.d.ts +12 -2
- package/dist/client/router-types.d.ts.map +1 -1
- package/dist/client/router.d.ts.map +1 -1
- package/dist/client/segment-cache.d.ts +39 -0
- package/dist/client/segment-cache.d.ts.map +1 -1
- package/dist/client/segment-context.d.ts.map +1 -1
- package/dist/client/segment-outlet.d.ts +25 -14
- package/dist/client/segment-outlet.d.ts.map +1 -1
- package/dist/client/segment-update-context.d.ts +3 -9
- package/dist/client/segment-update-context.d.ts.map +1 -1
- package/dist/client/slot-content-cache-context.d.ts +35 -0
- package/dist/client/slot-content-cache-context.d.ts.map +1 -0
- package/dist/client/ssr-data.d.ts +8 -2
- package/dist/client/ssr-data.d.ts.map +1 -1
- package/dist/client/state.d.ts +0 -15
- package/dist/client/state.d.ts.map +1 -1
- package/dist/client/use-pathname.d.ts +13 -11
- package/dist/client/use-pathname.d.ts.map +1 -1
- package/dist/client/use-search-params.d.ts +13 -13
- package/dist/client/use-search-params.d.ts.map +1 -1
- package/dist/client/use-segment-params.d.ts +18 -68
- package/dist/client/use-segment-params.d.ts.map +1 -1
- package/dist/config-types.d.ts +17 -0
- package/dist/config-types.d.ts.map +1 -1
- package/dist/config-validation.d.ts.map +1 -1
- package/dist/cookies/index.js +1 -1
- package/dist/dev-tools/holding-server.d.ts +15 -10
- package/dist/dev-tools/holding-server.d.ts.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +44 -43
- package/dist/index.js.map +1 -1
- package/dist/plugins/dev-server.d.ts.map +1 -1
- package/dist/plugins/entries.d.ts.map +1 -1
- package/dist/plugins/shims.d.ts.map +1 -1
- package/dist/plugins/static-build.d.ts +2 -2
- package/dist/plugins/static-build.d.ts.map +1 -1
- package/dist/routing/codegen-write.d.ts.map +1 -1
- package/dist/routing/index.js +2 -2
- package/dist/routing/interception-overlap.d.ts +35 -0
- package/dist/routing/interception-overlap.d.ts.map +1 -0
- package/dist/routing/interception.d.ts.map +1 -1
- package/dist/rsc-runtime/ssr.d.ts +3 -1
- package/dist/rsc-runtime/ssr.d.ts.map +1 -1
- package/dist/server/als-registry.d.ts +6 -0
- package/dist/server/als-registry.d.ts.map +1 -1
- package/dist/server/csp-nonce.d.ts +45 -0
- package/dist/server/csp-nonce.d.ts.map +1 -0
- package/dist/server/default-status-page.d.ts.map +1 -1
- package/dist/server/deny-renderer.d.ts.map +1 -1
- package/dist/server/flight-scripts.d.ts +5 -2
- package/dist/server/flight-scripts.d.ts.map +1 -1
- package/dist/server/html-injector-core.d.ts +17 -2
- package/dist/server/html-injector-core.d.ts.map +1 -1
- package/dist/server/html-injectors.d.ts +3 -2
- package/dist/server/html-injectors.d.ts.map +1 -1
- package/dist/server/index.js +2 -2
- package/dist/server/internal.js +86 -37
- package/dist/server/internal.js.map +1 -1
- package/dist/server/metadata-render.d.ts.map +1 -1
- package/dist/server/node-stream-transforms.d.ts +3 -17
- package/dist/server/node-stream-transforms.d.ts.map +1 -1
- package/dist/server/nuqs-ssr-provider.d.ts +7 -3
- package/dist/server/nuqs-ssr-provider.d.ts.map +1 -1
- package/dist/server/pipeline-phases.d.ts.map +1 -1
- package/dist/server/prebuilt/key-discipline.d.ts +32 -3
- package/dist/server/prebuilt/key-discipline.d.ts.map +1 -1
- package/dist/server/primitives.d.ts.map +1 -1
- package/dist/server/render-utils.d.ts +4 -3
- package/dist/server/render-utils.d.ts.map +1 -1
- package/dist/server/rsc-entry/action-middleware-runner.d.ts.map +1 -1
- package/dist/server/rsc-entry/error-renderer.d.ts.map +1 -1
- package/dist/server/rsc-entry/index.d.ts.map +1 -1
- package/dist/server/rsc-entry/ssr-renderer.d.ts.map +1 -1
- package/dist/server/ssr-bridge-types.d.ts +22 -2
- package/dist/server/ssr-bridge-types.d.ts.map +1 -1
- package/dist/server/ssr-entry.d.ts.map +1 -1
- package/dist/server/ssr-render.d.ts +5 -1
- package/dist/server/ssr-render.d.ts.map +1 -1
- package/dist/server/ssr-wrappers.d.ts +59 -27
- package/dist/server/ssr-wrappers.d.ts.map +1 -1
- package/dist/server/types.d.ts +10 -0
- package/dist/server/types.d.ts.map +1 -1
- package/dist/shims/navigation-rsc.d.ts +21 -0
- package/dist/shims/navigation-rsc.d.ts.map +1 -0
- package/docs/api/30-api-server.mdx +1 -0
- package/docs/api/35-api-typescript.mdx +4 -83
- package/docs/learn/03-fetching-data.mdx +1 -1
- package/docs/learn/{03b-access-control.mdx → 04-access-control.mdx} +2 -17
- package/docs/learn/05-the-flush-point.mdx +175 -0
- package/docs/learn/{05-typed-params.mdx → 06-typed-params.mdx} +1 -1
- package/docs/learn/07-typed-routes.mdx +25 -49
- package/docs/learn/{08-streaming.mdx → 09-streaming.mdx} +1 -7
- package/docs/learn/{10-middleware.mdx → 11-middleware.mdx} +1 -0
- package/package.json +3 -3
- package/src/adapters/nitro.ts +7 -7
- package/src/cache/singleflight.ts +5 -0
- package/src/client/browser-entry/hydrate.ts +54 -104
- package/src/client/browser-entry/index.ts +16 -6
- package/src/client/browser-entry/post-hydration.ts +3 -2
- package/src/client/browser-entry/router-init.ts +84 -33
- package/src/client/global-context.ts +31 -0
- package/src/client/internal.ts +1 -2
- package/src/client/link.tsx +18 -18
- package/src/client/location-search.ts +15 -0
- package/src/client/navigation-api.ts +4 -2
- package/src/client/navigation-commit.ts +48 -2
- package/src/client/navigation-context.ts +25 -37
- package/src/client/navigation-root.tsx +55 -411
- package/src/client/navigation-transition.ts +278 -0
- package/src/client/nuqs-adapter.tsx +4 -5
- package/src/client/params-context.ts +13 -18
- package/src/client/react-root.ts +72 -0
- package/src/client/router-lifecycle.ts +1 -1
- package/src/client/router-pipeline.ts +96 -22
- package/src/client/router-types.ts +12 -2
- package/src/client/router.ts +48 -36
- package/src/client/segment-cache.ts +70 -2
- package/src/client/segment-context.ts +7 -4
- package/src/client/segment-outlet.tsx +41 -86
- package/src/client/segment-update-context.ts +7 -26
- package/src/client/slot-content-cache-context.ts +43 -0
- package/src/client/ssr-data.ts +8 -2
- package/src/client/state.ts +0 -26
- package/src/client/use-pathname.ts +21 -31
- package/src/client/use-search-params.ts +31 -29
- package/src/client/use-segment-params.ts +27 -126
- package/src/config-types.ts +17 -0
- package/src/config-validation.ts +17 -0
- package/src/dev-tools/holding-server.ts +23 -12
- package/src/index.ts +26 -11
- package/src/plugins/dev-server.ts +9 -12
- package/src/plugins/entries.ts +3 -0
- package/src/plugins/shims.ts +8 -7
- package/src/plugins/static-build.ts +9 -5
- package/src/react-canary.d.ts +2 -0
- package/src/routing/codegen-write.ts +2 -0
- package/src/routing/interception-overlap.ts +141 -0
- package/src/routing/interception.ts +118 -5
- package/src/rsc-runtime/ssr.ts +3 -2
- package/src/server/als-registry.ts +6 -0
- package/src/server/csp-nonce.ts +70 -0
- package/src/server/default-status-page.ts +1 -0
- package/src/server/deny-renderer.ts +7 -3
- package/src/server/flight-scripts.ts +9 -4
- package/src/server/html-injector-core.ts +26 -9
- package/src/server/html-injectors.ts +8 -8
- package/src/server/metadata-render.ts +26 -4
- package/src/server/node-stream-transforms.ts +7 -20
- package/src/server/nuqs-ssr-provider.tsx +8 -7
- package/src/server/pipeline-phases.ts +5 -0
- package/src/server/prebuilt/key-discipline.ts +82 -13
- package/src/server/prebuilt-runtime.ts +2 -2
- package/src/server/primitives.ts +4 -4
- package/src/server/render-utils.ts +8 -4
- package/src/server/rsc-entry/action-middleware-runner.ts +7 -0
- package/src/server/rsc-entry/error-renderer.ts +5 -2
- package/src/server/rsc-entry/index.ts +8 -0
- package/src/server/rsc-entry/ssr-renderer.ts +11 -4
- package/src/server/ssr-bridge-types.ts +22 -2
- package/src/server/ssr-entry.ts +35 -28
- package/src/server/ssr-render.ts +13 -4
- package/src/server/ssr-wrappers.tsx +81 -61
- package/src/server/types.ts +10 -0
- package/src/shared/slot-params.ts +3 -4
- package/src/shims/navigation-rsc.ts +47 -0
- package/dist/_chunks/build-manifest-DWppEdLB.js.map +0 -1
- package/dist/_chunks/cache-api-CQeYzA5g.js.map +0 -1
- package/dist/_chunks/convention-lint-DO10_pVl.js.map +0 -1
- package/dist/_chunks/href-validation-CMc5JRls.js.map +0 -1
- package/dist/_chunks/scanner-BRIOmHE2.js.map +0 -1
- package/dist/_chunks/segment-context-CjOlyB8Y.js.map +0 -1
- package/dist/_chunks/slot-params-BCTmZkQB.js +0 -76
- package/dist/_chunks/slot-params-BCTmZkQB.js.map +0 -1
- package/dist/_chunks/ssr-data-Ya2HJPFp.js.map +0 -1
- package/dist/_chunks/use-segment-params-DzTBpkvj.js +0 -398
- package/dist/_chunks/use-segment-params-DzTBpkvj.js.map +0 -1
- package/docs/learn/04-loading-states.mdx +0 -67
- package/docs/learn/04b-the-flush-point.mdx +0 -115
- package/docs/learn/12-client-navigation.mdx +0 -176
- package/docs/learn/13-configuration.mdx +0 -166
- package/docs/more/01-advanced-routing.mdx +0 -344
- package/docs/more/02-advanced-forms.mdx +0 -137
- package/docs/more/03-coming-from-nextjs.mdx +0 -186
- package/docs/more/04-metadata-and-fonts.mdx +0 -193
- package/docs/more/04b-mdx.mdx +0 -229
- package/docs/more/05-content-collections.mdx +0 -90
- package/docs/more/06-instrumentation.mdx +0 -214
- package/docs/more/07-security.mdx +0 -129
- package/docs/more/08-developer-experience.mdx +0 -134
- package/docs/more/40-why-timber.mdx +0 -50
- package/docs/more/41-timber-vs-nextjs.mdx +0 -81
- package/docs/more/42-timber-vs-others.mdx +0 -68
- package/docs/more/50-ai-agent-instructions.mdx +0 -171
- /package/docs/learn/{06-forms-and-actions.mdx → 08-forms-and-actions.mdx} +0 -0
- /package/docs/learn/{09-caching.mdx → 10-caching.mdx} +0 -0
- /package/docs/learn/{11-error-handling.mdx → 12-error-handling.mdx} +0 -0
- /package/docs/learn/{14-deploying.mdx → 13-deploying.mdx} +0 -0
|
@@ -1,171 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
title: 'AI Agent Instructions'
|
|
3
|
-
description: 'Structured reference for AI coding agents working with timber.js — key differences from Next.js, import paths, common mistakes, and reading order.'
|
|
4
|
-
slug: 'ai-agent-instructions'
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
# AI Agent Instructions
|
|
8
|
-
|
|
9
|
-
This page is for AI coding agents (Claude Code, Cursor, Copilot, Codex, etc.) and developers who paste context into agent prompts. It is concise and structured for machine consumption — but useful as a quick reference for humans too.
|
|
10
|
-
|
|
11
|
-
## Fetching These Docs as Markdown
|
|
12
|
-
|
|
13
|
-
Any timber.js documentation page can be fetched as plain markdown by sending an `Accept: text/markdown` header:
|
|
14
|
-
|
|
15
|
-
```bash
|
|
16
|
-
curl -H 'Accept: text/markdown' https://timberjs.com/docs/ai-agent-instructions
|
|
17
|
-
```
|
|
18
|
-
|
|
19
|
-
This returns the page content as `text/markdown` with a `203` status code, suitable for piping into agent context or saving to a file.
|
|
20
|
-
|
|
21
|
-
## How timber.js Docs Are Organized
|
|
22
|
-
|
|
23
|
-
| Location | Purpose | Audience |
|
|
24
|
-
| --- | --- | --- |
|
|
25
|
-
| `packages/website/content/docs/` | User-facing guides, tutorials, API reference | Developers building with timber |
|
|
26
|
-
| `design/` | Design decisions, architecture, internal specs | Contributors and agents implementing features |
|
|
27
|
-
| `CLAUDE.md` | Contributor workflow, commands, code style | Agents working on timber itself |
|
|
28
|
-
|
|
29
|
-
**Read the user-facing docs for building apps.** Read the design docs only when you need to understand _why_ something works the way it does or when contributing to timber itself.
|
|
30
|
-
|
|
31
|
-
## Reading Order by Task
|
|
32
|
-
|
|
33
|
-
**Starting a new project:**
|
|
34
|
-
1. [Introduction](/docs/introduction) — what timber is and its philosophy
|
|
35
|
-
2. [Quick Start](/docs/quick-start) — project setup
|
|
36
|
-
3. [Pages and Layouts](/docs/pages-and-layouts) — routing basics
|
|
37
|
-
4. [Configuration](/docs/configuration) — `timber.config.ts`
|
|
38
|
-
|
|
39
|
-
**Adding a feature:**
|
|
40
|
-
1. [API: @timber-js/app/server](/docs/api-server) — server exports
|
|
41
|
-
2. [API: @timber-js/app/client](/docs/api-client) — client exports
|
|
42
|
-
3. The relevant guide (caching, forms, middleware, etc.)
|
|
43
|
-
|
|
44
|
-
**Debugging:**
|
|
45
|
-
1. [Coming from Next.js](/docs/coming-from-nextjs) — if the code assumes Next.js patterns
|
|
46
|
-
2. [The Flush Point](/docs/the-flush-point) — if status codes or headers are wrong
|
|
47
|
-
3. [Error Handling](/docs/error-handling) — deny, error boundaries, status files
|
|
48
|
-
|
|
49
|
-
## Key Differences from Next.js
|
|
50
|
-
|
|
51
|
-
These are the things you will get wrong if you assume Next.js behavior.
|
|
52
|
-
|
|
53
|
-
| Concept | Next.js | timber.js |
|
|
54
|
-
| --- | --- | --- |
|
|
55
|
-
| Default component type | Client components need `'use client'` | **All components are server components** by default. Only add `'use client'` when you need browser APIs or hooks. |
|
|
56
|
-
| Fetch caching | `fetch()` is patched with implicit caching | `fetch()` is **never patched**. Use `cache.data()` from `@timber-js/app/cache` explicitly. |
|
|
57
|
-
| ISR | `revalidate` option | **Does not exist.** Use `cache.data()` with TTL and tags. |
|
|
58
|
-
| `loading.tsx` | Convention for auto-Suspense | **Does not exist.** Use `<Suspense>` explicitly. |
|
|
59
|
-
| Middleware | Single global `middleware.ts` with matchers | Per-segment `middleware.ts` files + global `proxy.ts`. One-arg signature: `middleware(ctx)`. |
|
|
60
|
-
| `notFound()` | `notFound()` from `next/navigation` | `deny(404)` from `@timber-js/app/server`. Sends a real HTTP 404. |
|
|
61
|
-
| `redirect()` | `redirect()` from `next/navigation` | `redirect()` from `@timber-js/app/server`. Same concept, different import. |
|
|
62
|
-
| Search params | Untyped `useSearchParams()` | Typed `defineSearchParams()` with Zod schemas, in any module you import. |
|
|
63
|
-
| Auth pattern | In middleware or components | `access.ts` per segment with slot degradation. |
|
|
64
|
-
| Forms | `useFormState` / `useFormStatus` | `createActionClient` + `useActionState` returns a 4-tuple. Forms work without JS. |
|
|
65
|
-
|
|
66
|
-
## Import Map
|
|
67
|
-
|
|
68
|
-
| What you need | Import from |
|
|
69
|
-
| --- | --- |
|
|
70
|
-
| `deny`, `redirect`, `getHeaders`, `getCookieJar`, `createActionClient` | `@timber-js/app/server` |
|
|
71
|
-
| `Link`, `useRouter`, `usePathname`, `useActionState` | `@timber-js/app/client` |
|
|
72
|
-
| `cache`, `CacheHandler` | `@timber-js/app/cache` |
|
|
73
|
-
| `defineSearchParams` | `@timber-js/app/search-params` |
|
|
74
|
-
| `defineSchema`, `InferCodecType` | `@timber-js/app/params` |
|
|
75
|
-
| Content collection data | `content-collections` |
|
|
76
|
-
| `Metadata` type | `@timber-js/app/server` |
|
|
77
|
-
|
|
78
|
-
There is **no** `@timber-js/app` default import. Always use the subpath exports above.
|
|
79
|
-
|
|
80
|
-
## Project Structure
|
|
81
|
-
|
|
82
|
-
```
|
|
83
|
-
app/ # Route tree — file-system routing
|
|
84
|
-
proxy.ts # Global request handler (like global middleware)
|
|
85
|
-
layout.tsx # Root layout
|
|
86
|
-
page.tsx # Home page
|
|
87
|
-
[segment]/
|
|
88
|
-
page.tsx # Dynamic route
|
|
89
|
-
middleware.ts # Per-segment middleware
|
|
90
|
-
access.ts # Per-segment authorization
|
|
91
|
-
denied.tsx # Rendered when access.ts denies
|
|
92
|
-
error.tsx # Error boundary for this segment
|
|
93
|
-
search-params.ts # Search param definitions (ordinary module, not a convention)
|
|
94
|
-
schema.ts # Segment param schemas (from @timber-js/app/params)
|
|
95
|
-
content/ # Content collections (outside route tree)
|
|
96
|
-
timber.config.ts # Framework configuration
|
|
97
|
-
mdx-components.tsx # Custom MDX component mappings (optional)
|
|
98
|
-
content-collections.ts # Collection definitions (optional)
|
|
99
|
-
```
|
|
100
|
-
|
|
101
|
-
## Common Mistakes
|
|
102
|
-
|
|
103
|
-
1. **Importing from `next/*`** — there is no `next` package. Use `@timber-js/app/server` and `@timber-js/app/client`. Exception: `next/navigation`'s `redirect()` and `notFound()` are shimmed for compatibility.
|
|
104
|
-
|
|
105
|
-
2. **Adding `'use client'` to everything** — components are server components by default. Only add `'use client'` when you need browser APIs, event handlers, or React hooks like `useState`/`useEffect`.
|
|
106
|
-
|
|
107
|
-
The exception: `error.tsx`, `global-error.tsx`, and component status files (`404.tsx`, `4xx.tsx`, `503.tsx`, …) **always** need `'use client'`. timber passes them to a client error boundary as a prop, so a server component there breaks every page under that segment. The build rejects it and names the file. MDX status files (`404.mdx`) are exempt.
|
|
108
|
-
|
|
109
|
-
3. **Using `fetch()` and expecting caching** — timber never patches `fetch`. Wrap data-fetching functions in `cache.data()` from `@timber-js/app/cache` when you want caching.
|
|
110
|
-
|
|
111
|
-
4. **Creating `loading.tsx` files** — this convention does not exist. Use `<Suspense>` with an explicit fallback where you want streaming.
|
|
112
|
-
|
|
113
|
-
5. **Using ISR patterns** (`revalidate`, `unstable_cache`) — ISR does not exist. Use `cache.data()` with `{ ttl: seconds, tags: ['tag'] }`.
|
|
114
|
-
|
|
115
|
-
6. **Calling `notFound()`** — use `deny(404)` from `@timber-js/app/server` instead. It sends a real HTTP 404 status code.
|
|
116
|
-
|
|
117
|
-
7. **Putting all middleware in one file** — middleware is per-segment. Place `middleware.ts` at the route level that matches the concern. Use `proxy.ts` for global concerns.
|
|
118
|
-
|
|
119
|
-
8. **Assuming `useSearchParams()` exists** — use `defineSearchParams()` in any module with Zod schemas, then access via `.get()` (server) or `.useQueryStates()` (client).
|
|
120
|
-
|
|
121
|
-
## Quick Patterns
|
|
122
|
-
|
|
123
|
-
### Data fetching with caching
|
|
124
|
-
|
|
125
|
-
```tsx
|
|
126
|
-
import { cache } from '@timber-js/app/cache';
|
|
127
|
-
|
|
128
|
-
const getProducts = cache.data(
|
|
129
|
-
async () => db.products.findMany(),
|
|
130
|
-
{ ttl: 300, tags: ['products'] }
|
|
131
|
-
);
|
|
132
|
-
|
|
133
|
-
export default async function Page() {
|
|
134
|
-
const products = await getProducts();
|
|
135
|
-
return <ProductList products={products} />;
|
|
136
|
-
}
|
|
137
|
-
```
|
|
138
|
-
|
|
139
|
-
### 404 handling
|
|
140
|
-
|
|
141
|
-
```tsx
|
|
142
|
-
import { deny } from '@timber-js/app/server';
|
|
143
|
-
|
|
144
|
-
export default async function Page({ params }: { params: Promise<{ id: string }> }) {
|
|
145
|
-
const { id } = await params;
|
|
146
|
-
const item = await getItem(id);
|
|
147
|
-
if (!item) deny(404);
|
|
148
|
-
return <Item item={item} />;
|
|
149
|
-
}
|
|
150
|
-
```
|
|
151
|
-
|
|
152
|
-
### Per-segment middleware
|
|
153
|
-
|
|
154
|
-
```ts title="app/dashboard/middleware.ts"
|
|
155
|
-
import type { MiddlewareContext } from '@timber-js/app/server';
|
|
156
|
-
|
|
157
|
-
export default async function middleware(ctx: MiddlewareContext) {
|
|
158
|
-
ctx.headers.set('X-Dashboard', 'true');
|
|
159
|
-
}
|
|
160
|
-
```
|
|
161
|
-
|
|
162
|
-
### Access control
|
|
163
|
-
|
|
164
|
-
```ts title="app/(auth)/access.ts"
|
|
165
|
-
import { redirect, getCookieJar } from '@timber-js/app/server';
|
|
166
|
-
|
|
167
|
-
export default async function access() {
|
|
168
|
-
const session = getSession(getCookieJar());
|
|
169
|
-
if (!session) redirect('/login');
|
|
170
|
-
}
|
|
171
|
-
```
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|