@barefootjs/cli 0.1.0
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/docs/core/README.md +84 -0
- package/dist/docs/core/adapters/adapter-architecture.md +262 -0
- package/dist/docs/core/adapters/csr.md +78 -0
- package/dist/docs/core/adapters/custom-adapter.md +357 -0
- package/dist/docs/core/adapters/go-template-adapter.md +269 -0
- package/dist/docs/core/adapters/hono-adapter.md +199 -0
- package/dist/docs/core/adapters.md +37 -0
- package/dist/docs/core/advanced/code-splitting.md +142 -0
- package/dist/docs/core/advanced/compiler-internals.md +331 -0
- package/dist/docs/core/advanced/error-codes.md +261 -0
- package/dist/docs/core/advanced/ir-schema.md +65 -0
- package/dist/docs/core/advanced/performance.md +115 -0
- package/dist/docs/core/advanced/xyflow-browser-bundle.md +69 -0
- package/dist/docs/core/advanced.md +11 -0
- package/dist/docs/core/components/children-slots.md +150 -0
- package/dist/docs/core/components/component-authoring.md +207 -0
- package/dist/docs/core/components/context-api.md +236 -0
- package/dist/docs/core/components/portals.md +192 -0
- package/dist/docs/core/components/props-type-safety.md +97 -0
- package/dist/docs/core/components/styling.md +37 -0
- package/dist/docs/core/components.md +19 -0
- package/dist/docs/core/core-concepts/ai-native.md +83 -0
- package/dist/docs/core/core-concepts/backend-freedom.md +31 -0
- package/dist/docs/core/core-concepts/how-it-works.md +147 -0
- package/dist/docs/core/core-concepts/mpa-style.md +36 -0
- package/dist/docs/core/core-concepts/reactivity.md +35 -0
- package/dist/docs/core/core-concepts.md +28 -0
- package/dist/docs/core/introduction.md +87 -0
- package/dist/docs/core/llms.txt +53 -0
- package/dist/docs/core/quick-start.mdx +160 -0
- package/dist/docs/core/reactivity/create-effect.md +125 -0
- package/dist/docs/core/reactivity/create-memo.md +91 -0
- package/dist/docs/core/reactivity/create-signal.md +128 -0
- package/dist/docs/core/reactivity/on-cleanup.md +67 -0
- package/dist/docs/core/reactivity/on-mount.md +70 -0
- package/dist/docs/core/reactivity/props-reactivity.md +91 -0
- package/dist/docs/core/reactivity/untrack.md +69 -0
- package/dist/docs/core/reactivity.md +28 -0
- package/dist/docs/core/rendering/client-directive.md +82 -0
- package/dist/docs/core/rendering/fragment.md +43 -0
- package/dist/docs/core/rendering/jsx-compatibility.md +163 -0
- package/dist/docs/core/rendering.md +14 -0
- package/dist/index.js +25490 -0
- package/dist/tokens.json +74 -0
- package/package.json +37 -0
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
# BarefootJS Documentation
|
|
2
|
+
|
|
3
|
+
## Table of Contents
|
|
4
|
+
|
|
5
|
+
### 1. [Introduction](./introduction.md)
|
|
6
|
+
|
|
7
|
+
- What is BarefootJS?
|
|
8
|
+
- Why BarefootJS?
|
|
9
|
+
- Design Philosophy
|
|
10
|
+
|
|
11
|
+
### 2. [Quick Start](./quick-start.mdx)
|
|
12
|
+
|
|
13
|
+
- Scaffold an app with `npm create barefootjs@latest`
|
|
14
|
+
- Run the dev server and edit the starter Counter
|
|
15
|
+
- Tour of the generated project structure
|
|
16
|
+
|
|
17
|
+
### 3. [Core Concepts](./core-concepts.md)
|
|
18
|
+
|
|
19
|
+
- [Backend Freedom](./core-concepts/backend-freedom.md) — How adapters let the same JSX run on any server
|
|
20
|
+
- [MPA-style Development](./core-concepts/mpa-style.md) — Server-rendering by default, JS only where marked
|
|
21
|
+
- [Fine-grained Reactivity](./core-concepts/reactivity.md) — Signals, effects, memos — no virtual DOM needed
|
|
22
|
+
- [AI-native Development](./core-concepts/ai-native.md) — Testable IR, CLI discovery, AI-assisted workflows
|
|
23
|
+
- [How It Works](./core-concepts/how-it-works.md) — Two-phase compilation, hydration markers, clean overrides
|
|
24
|
+
|
|
25
|
+
### 4. [Reactivity](./reactivity.md)
|
|
26
|
+
|
|
27
|
+
- [`createSignal`](./reactivity/create-signal.md) — Create a reactive value
|
|
28
|
+
- [`createEffect`](./reactivity/create-effect.md) — Run side effects when dependencies change
|
|
29
|
+
- [`createMemo`](./reactivity/create-memo.md) — Create a cached derived value
|
|
30
|
+
- [`onMount`](./reactivity/on-mount.md) — Run once on component initialization
|
|
31
|
+
- [`onCleanup`](./reactivity/on-cleanup.md) — Register cleanup for effects and lifecycle
|
|
32
|
+
- [`untrack`](./reactivity/untrack.md) — Read signals without tracking dependencies
|
|
33
|
+
- [Props Reactivity](./reactivity/props-reactivity.md) — Gotchas with destructuring
|
|
34
|
+
|
|
35
|
+
### 5. [Templates & Rendering](./rendering.md)
|
|
36
|
+
|
|
37
|
+
- [JSX Compatibility](./rendering/jsx-compatibility.md) — What works, what doesn't, and what differs
|
|
38
|
+
- [Fragment](./rendering/fragment.md) — Fragment support and hydration behavior
|
|
39
|
+
- [`/* @client */` Directive](./rendering/client-directive.md) — Skip server evaluation for client-only expressions
|
|
40
|
+
|
|
41
|
+
### 6. [Components](./components.md)
|
|
42
|
+
|
|
43
|
+
- [Component Authoring](./components/component-authoring.md) — Server components, client components, and the compilation model
|
|
44
|
+
- [Props & Type Safety](./components/props-type-safety.md) — Typing props, defaults, and rest spreading
|
|
45
|
+
- [Children & Slots](./components/children-slots.md) — Children prop, the `Slot` component, and the `asChild` pattern
|
|
46
|
+
- [Context API](./components/context-api.md) — Sharing state with `createContext` / `useContext`
|
|
47
|
+
- [Portals](./components/portals.md) — Rendering elements outside their parent DOM hierarchy
|
|
48
|
+
|
|
49
|
+
### 7. [Adapters](./adapters.md)
|
|
50
|
+
|
|
51
|
+
- [Adapter Architecture](./adapters/adapter-architecture.md) — How adapters work, the `TemplateAdapter` interface, and the IR contract
|
|
52
|
+
- [Hono Adapter](./adapters/hono-adapter.md) — Configuration and output format for Hono / JSX-based servers
|
|
53
|
+
- [Go Template Adapter](./adapters/go-template-adapter.md) — Configuration and output format for Go `html/template`
|
|
54
|
+
- [CSR (Client-Side Rendering)](./adapters/csr.md) — Static-hosting renderer: emit client JS only, no SSR template
|
|
55
|
+
- [Writing a Custom Adapter](./adapters/custom-adapter.md) — Step-by-step guide to implementing your own adapter
|
|
56
|
+
|
|
57
|
+
### 8. [Advanced](./advanced.md)
|
|
58
|
+
|
|
59
|
+
- [IR Schema Reference](./advanced/ir-schema.md) — Node types, metadata, hydration markers
|
|
60
|
+
- [Compiler Internals](./advanced/compiler-internals.md) — Pipeline phases, reactivity analysis, code generation
|
|
61
|
+
- [Error Codes Reference](./advanced/error-codes.md) — All BF001–BF043 errors with solutions
|
|
62
|
+
- [Performance Optimization](./advanced/performance.md) — Minimal client JS, fast hydration, efficient reactivity
|
|
63
|
+
|
|
64
|
+
---
|
|
65
|
+
|
|
66
|
+
## Documentation Conventions
|
|
67
|
+
|
|
68
|
+
Code examples use **switchable tabs** for adapter output and package manager commands. Preferences persist across pages.
|
|
69
|
+
|
|
70
|
+
**Adapter** — Hono (default) or Go Template:
|
|
71
|
+
|
|
72
|
+
<!-- tabs:adapter -->
|
|
73
|
+
- Hono (default)
|
|
74
|
+
- Go Template
|
|
75
|
+
|
|
76
|
+
**Package Manager** — npm (default), bun, pnpm, or yarn:
|
|
77
|
+
|
|
78
|
+
<!-- tabs:pm -->
|
|
79
|
+
- npm (default)
|
|
80
|
+
- bun
|
|
81
|
+
- pnpm
|
|
82
|
+
- yarn
|
|
83
|
+
|
|
84
|
+
> Sections marked with 💡 explain JSX and TypeScript concepts for developers from Go, Python, or other backend languages.
|
|
@@ -0,0 +1,262 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Adapter Architecture
|
|
3
|
+
description: How adapters convert the compiler's IR into server-renderable template formats.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Adapter Architecture
|
|
7
|
+
|
|
8
|
+
An adapter converts the compiler's IR into a template format your server can render.
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
## Role
|
|
12
|
+
|
|
13
|
+
1. **Phase 1** parses JSX → backend-agnostic `ComponentIR` (JSON tree)
|
|
14
|
+
2. **Phase 2a** adapter converts IR → marked template in target language
|
|
15
|
+
3. **Phase 2b** generates client JS from IR (no adapter involved)
|
|
16
|
+
|
|
17
|
+
```
|
|
18
|
+
ComponentIR (JSON)
|
|
19
|
+
↓
|
|
20
|
+
┌───────────────────────────────┐
|
|
21
|
+
│ TemplateAdapter │
|
|
22
|
+
│ │
|
|
23
|
+
│ renderElement() │
|
|
24
|
+
│ renderExpression() │
|
|
25
|
+
│ renderConditional() │
|
|
26
|
+
│ renderLoop() │
|
|
27
|
+
│ renderComponent() │
|
|
28
|
+
│ ... │
|
|
29
|
+
└───────────────────────────────┘
|
|
30
|
+
↓
|
|
31
|
+
Marked Template + optional types
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Each IR node is translated into the target template language with hydration markers (`bf-*` attributes).
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
## `TemplateAdapter` Interface
|
|
38
|
+
|
|
39
|
+
```typescript
|
|
40
|
+
interface TemplateAdapter {
|
|
41
|
+
name: string // Adapter identifier (e.g., 'hono', 'go-template')
|
|
42
|
+
extension: string // Output file extension (e.g., '.tsx', '.tmpl')
|
|
43
|
+
|
|
44
|
+
// Main entry point
|
|
45
|
+
generate(ir: ComponentIR, options?: AdapterGenerateOptions): AdapterOutput
|
|
46
|
+
|
|
47
|
+
// Node rendering — one method per IR node type
|
|
48
|
+
renderNode(node: IRNode): string
|
|
49
|
+
renderElement(element: IRElement): string
|
|
50
|
+
renderExpression(expr: IRExpression): string
|
|
51
|
+
renderConditional(cond: IRConditional): string
|
|
52
|
+
renderLoop(loop: IRLoop): string
|
|
53
|
+
renderComponent(comp: IRComponent): string
|
|
54
|
+
|
|
55
|
+
// Hydration markers
|
|
56
|
+
renderScopeMarker(instanceIdExpr: string): string
|
|
57
|
+
renderSlotMarker(slotId: string): string
|
|
58
|
+
renderCondMarker(condId: string): string
|
|
59
|
+
|
|
60
|
+
// Optional: type generation for typed languages
|
|
61
|
+
generateTypes?(ir: ComponentIR): string | null
|
|
62
|
+
}
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### `generate()`
|
|
66
|
+
|
|
67
|
+
```typescript
|
|
68
|
+
interface AdapterOutput {
|
|
69
|
+
template: string // The generated template code
|
|
70
|
+
types?: string // Optional generated types (Go structs, etc.)
|
|
71
|
+
extension: string // File extension for the output
|
|
72
|
+
}
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### `AdapterGenerateOptions`
|
|
76
|
+
|
|
77
|
+
```typescript
|
|
78
|
+
interface AdapterGenerateOptions {
|
|
79
|
+
skipScriptRegistration?: boolean // For child components bundled in parent
|
|
80
|
+
scriptBaseName?: string // For non-default exports sharing a parent's client JS
|
|
81
|
+
}
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
### Node rendering methods
|
|
85
|
+
|
|
86
|
+
| Method | IR Node | Responsibility |
|
|
87
|
+
|--------|---------|----------------|
|
|
88
|
+
| `renderElement()` | `IRElement` | HTML elements with attributes, events, and hydration markers |
|
|
89
|
+
| `renderExpression()` | `IRExpression` | Dynamic expressions (e.g., `{count()}`, `{props.name}`) |
|
|
90
|
+
| `renderConditional()` | `IRConditional` | Ternaries and `&&`/`||` expressions |
|
|
91
|
+
| `renderLoop()` | `IRLoop` | `.map()`, `.filter().map()`, `.sort().map()` chains |
|
|
92
|
+
| `renderComponent()` | `IRComponent` | Nested component invocations |
|
|
93
|
+
| `renderNode()` | `IRNode` | Dispatcher — routes to the correct method based on node type |
|
|
94
|
+
|
|
95
|
+
### Hydration marker methods
|
|
96
|
+
|
|
97
|
+
| Method | Marker | Purpose |
|
|
98
|
+
|--------|--------|---------|
|
|
99
|
+
| `renderScopeMarker()` | `bf-s` | Component boundary for scoped hydration |
|
|
100
|
+
| `renderSlotMarker()` | `bf` | Interactive element identifier |
|
|
101
|
+
| `renderCondMarker()` | `bf-c` | Conditional block for DOM switching |
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
## `BaseAdapter` Class
|
|
105
|
+
|
|
106
|
+
`BaseAdapter` implements the `TemplateAdapter` interface with a `renderChildren()` utility:
|
|
107
|
+
|
|
108
|
+
```typescript
|
|
109
|
+
abstract class BaseAdapter implements TemplateAdapter {
|
|
110
|
+
abstract name: string
|
|
111
|
+
abstract extension: string
|
|
112
|
+
|
|
113
|
+
// ... all abstract methods from TemplateAdapter
|
|
114
|
+
|
|
115
|
+
renderChildren(children: IRNode[]): string {
|
|
116
|
+
return children.map(child => this.renderNode(child)).join('')
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
Extending `BaseAdapter` is optional.
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
## IR Node Types
|
|
125
|
+
|
|
126
|
+
Each adapter must handle all IR node types:
|
|
127
|
+
|
|
128
|
+
### `IRElement`
|
|
129
|
+
|
|
130
|
+
An HTML element with attributes, events, and children.
|
|
131
|
+
|
|
132
|
+
```typescript
|
|
133
|
+
{
|
|
134
|
+
type: 'element'
|
|
135
|
+
tag: string // 'div', 'button', 'input', etc.
|
|
136
|
+
attrs: IRAttribute[] // Static and dynamic attributes
|
|
137
|
+
events: IREvent[] // Event handlers (onClick, onChange, etc.)
|
|
138
|
+
children: IRNode[] // Child nodes
|
|
139
|
+
slotId: string | null // Hydration slot ID (e.g., 's0')
|
|
140
|
+
needsScope: boolean // True if this is the component root
|
|
141
|
+
}
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
### `IRExpression`
|
|
145
|
+
|
|
146
|
+
A dynamic expression in the template.
|
|
147
|
+
|
|
148
|
+
```typescript
|
|
149
|
+
{
|
|
150
|
+
type: 'expression'
|
|
151
|
+
expr: string // The JS expression (e.g., 'count()', 'props.name')
|
|
152
|
+
reactive: boolean // True if the expression depends on signals
|
|
153
|
+
slotId: string | null // Slot ID for client updates
|
|
154
|
+
clientOnly?: boolean // True if wrapped in /* @client */
|
|
155
|
+
}
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
### `IRConditional`
|
|
159
|
+
|
|
160
|
+
A ternary or logical expression that produces different output.
|
|
161
|
+
|
|
162
|
+
```typescript
|
|
163
|
+
{
|
|
164
|
+
type: 'conditional'
|
|
165
|
+
condition: string // The JS condition
|
|
166
|
+
whenTrue: IRNode // Rendered when condition is true
|
|
167
|
+
whenFalse: IRNode // Rendered when condition is false
|
|
168
|
+
reactive: boolean // True if the condition depends on signals
|
|
169
|
+
slotId: string | null // Slot ID for DOM switching
|
|
170
|
+
}
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
### `IRLoop`
|
|
174
|
+
|
|
175
|
+
An array iteration (`.map()`, optionally chained with `.filter()` or `.sort()`).
|
|
176
|
+
|
|
177
|
+
```typescript
|
|
178
|
+
{
|
|
179
|
+
type: 'loop'
|
|
180
|
+
array: string // The array expression
|
|
181
|
+
param: string // Iterator parameter name
|
|
182
|
+
index: string | null // Index parameter name
|
|
183
|
+
children: IRNode[] // Loop body
|
|
184
|
+
isStaticArray: boolean // True if iterating a prop (not a signal)
|
|
185
|
+
filterPredicate?: {...} // For .filter().map() chains
|
|
186
|
+
sortComparator?: {...} // For .sort().map() chains
|
|
187
|
+
}
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
### `IRComponent`
|
|
191
|
+
|
|
192
|
+
A nested component invocation.
|
|
193
|
+
|
|
194
|
+
```typescript
|
|
195
|
+
{
|
|
196
|
+
type: 'component'
|
|
197
|
+
name: string // Component name (e.g., 'TodoItem')
|
|
198
|
+
props: IRProp[] // Props passed to the component
|
|
199
|
+
children: IRNode[] // Children (slots)
|
|
200
|
+
slotId: string | null // Slot ID if parent binds event handlers
|
|
201
|
+
}
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
### Other node types
|
|
205
|
+
|
|
206
|
+
| Type | Description |
|
|
207
|
+
|------|-------------|
|
|
208
|
+
| `IRText` | Static text content |
|
|
209
|
+
| `IRFragment` | Fragment (`<>...</>`) wrapper |
|
|
210
|
+
| `IRSlot` | `{children}` or `<Slot />` placeholder |
|
|
211
|
+
| `IRIfStatement` | Top-level if/else if/else blocks |
|
|
212
|
+
| `IRProvider` | Context provider wrapper |
|
|
213
|
+
| `IRTemplateLiteral` | Template literal expressions |
|
|
214
|
+
|
|
215
|
+
|
|
216
|
+
## Hydration Markers
|
|
217
|
+
|
|
218
|
+
`bf-*` attributes tell the client JS where to attach behavior:
|
|
219
|
+
|
|
220
|
+
| Marker | Example | Purpose |
|
|
221
|
+
|--------|---------|---------|
|
|
222
|
+
| `bf-s` | `<div bf-s="Counter_a1b2">` | Component boundary — scopes all queries inside |
|
|
223
|
+
| `bf` | `<p bf="s0">` | Interactive element — target for effects and event handlers |
|
|
224
|
+
| `bf-c` | `<div bf-c="s2">` | Conditional block — target for DOM switching |
|
|
225
|
+
|
|
226
|
+
|
|
227
|
+
|
|
228
|
+
## Script Registration
|
|
229
|
+
|
|
230
|
+
Adapters register client JS during server rendering to ensure each script loads exactly once:
|
|
231
|
+
|
|
232
|
+
- **Hono**: `useRequestContext()` collects script paths; `BfScripts` renders the `<script>` tags.
|
|
233
|
+
- **Go Template**: `ScriptCollector` tracks needed scripts; renders `<script>` tags at page end.
|
|
234
|
+
|
|
235
|
+
|
|
236
|
+
## Type Generation
|
|
237
|
+
|
|
238
|
+
For typed backends, `generateTypes()` produces type definitions alongside the template. The Go Template adapter generates:
|
|
239
|
+
|
|
240
|
+
- **Go structs** for component input and props types
|
|
241
|
+
- **JSON tags** for prop serialization
|
|
242
|
+
- **Constructor functions** like `New{Component}Props()` with default values
|
|
243
|
+
|
|
244
|
+
```go
|
|
245
|
+
// Generated by GoTemplateAdapter
|
|
246
|
+
type CounterInput struct {
|
|
247
|
+
Initial int `json:"initial"`
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
type CounterProps struct {
|
|
251
|
+
Initial int `json:"initial"`
|
|
252
|
+
ScopeID string `json:"scopeId"`
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
func NewCounterProps(input CounterInput) CounterProps {
|
|
256
|
+
return CounterProps{
|
|
257
|
+
Initial: input.Initial,
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
Dynamically-typed adapters (like Hono) skip this.
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: CSR (Client-Side Rendering)
|
|
3
|
+
description: Render BarefootJS components directly in the browser without a server-rendered template.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# CSR (Client-Side Rendering)
|
|
7
|
+
|
|
8
|
+
CSR renders BarefootJS components directly in the browser, without any server-rendered initial HTML. Use it when the server can't (or shouldn't) emit the initial markup.
|
|
9
|
+
|
|
10
|
+
Unlike the other entries in this section, CSR is not an IR→template adapter. It reuses the client-side template function that the compiler generates for each component, and mounts the resulting DOM into a container you pick.
|
|
11
|
+
|
|
12
|
+
## When to use CSR
|
|
13
|
+
|
|
14
|
+
Typical case: **static file hosting**. You have an HTML file you drop onto S3, GitHub Pages, or any static CDN — no backend renders the page. CSR lets you add interactive BarefootJS components to that page without setting up a server template.
|
|
15
|
+
|
|
16
|
+
When you do control the server (Hono, Go, etc.), prefer SSR + hydration instead. It renders faster to first paint and works without JavaScript enabled for static parts.
|
|
17
|
+
|
|
18
|
+
## Configuration
|
|
19
|
+
|
|
20
|
+
Use `createConfig` from `@barefootjs/client/build` in `barefoot.config.ts`. It wires the in-package `CSRAdapter` and skips marked template output automatically — no `clientOnly` flag is needed:
|
|
21
|
+
|
|
22
|
+
```typescript
|
|
23
|
+
// barefoot.config.ts
|
|
24
|
+
import { createConfig } from '@barefootjs/client/build'
|
|
25
|
+
|
|
26
|
+
export default createConfig({
|
|
27
|
+
components: ['./components'],
|
|
28
|
+
outDir: 'dist',
|
|
29
|
+
})
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
Build output:
|
|
33
|
+
|
|
34
|
+
```
|
|
35
|
+
dist/
|
|
36
|
+
└── components/
|
|
37
|
+
├── barefoot.js # client runtime bundle
|
|
38
|
+
└── Counter.client.js # compiled component
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## API
|
|
42
|
+
|
|
43
|
+
```typescript
|
|
44
|
+
import { render } from '@barefootjs/client/runtime'
|
|
45
|
+
|
|
46
|
+
render(container, componentName, props?)
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
| Parameter | Type | Description |
|
|
50
|
+
|-----------|------|-------------|
|
|
51
|
+
| `container` | `HTMLElement` | Target element. Its content is replaced. |
|
|
52
|
+
| `componentName` | `string` | Registered component name (same as the exported JSX function). |
|
|
53
|
+
| `props` | `Record<string, unknown>` | Optional props passed to the component. |
|
|
54
|
+
|
|
55
|
+
The component must be registered first by importing its `.client.js` file — that import triggers the compiler-generated `registerComponent` / `registerTemplate` calls.
|
|
56
|
+
|
|
57
|
+
## Example
|
|
58
|
+
|
|
59
|
+
```html
|
|
60
|
+
<!DOCTYPE html>
|
|
61
|
+
<html>
|
|
62
|
+
<head>
|
|
63
|
+
<script type="importmap">
|
|
64
|
+
{ "imports": { "@barefootjs/client/runtime": "/static/components/barefoot.js" } }
|
|
65
|
+
</script>
|
|
66
|
+
</head>
|
|
67
|
+
<body>
|
|
68
|
+
<div id="app"></div>
|
|
69
|
+
<script type="module">
|
|
70
|
+
import { render } from '@barefootjs/client/runtime'
|
|
71
|
+
await import('/static/components/Counter.client.js')
|
|
72
|
+
render(document.getElementById('app'), 'Counter', { initialCount: 0 })
|
|
73
|
+
</script>
|
|
74
|
+
</body>
|
|
75
|
+
</html>
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
See [`integrations/csr/`](https://github.com/piconic-ai/barefootjs/tree/main/integrations/csr) for a runnable end-to-end example.
|