uniweb 0.2.29 → 0.2.31

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/README.md CHANGED
@@ -32,7 +32,7 @@ my-project/
32
32
  │ ├── locales/ # i18n (hash-based translations)
33
33
  │ │ ├── manifest.json # Auto-extracted strings
34
34
  │ │ └── es.json # Spanish translations
35
- │ ├── main.js # 1-line entry point
35
+ │ ├── main.js # Entry point (~6 lines)
36
36
  │ ├── vite.config.js # 3-line config
37
37
  │ └── public/ # Static assets
38
38
 
@@ -226,7 +226,8 @@ uniweb build [options]
226
226
  | Option | Description |
227
227
  | ------------------- | --------------------------------------------------------------------- |
228
228
  | `--target <type>` | Build target: `foundation` or `site` (auto-detected if not specified) |
229
- | `--prerender` | Pre-render pages to static HTML (SSG) - site builds only |
229
+ | `--prerender` | Force pre-rendering (overrides site.yml) |
230
+ | `--no-prerender` | Skip pre-rendering (overrides site.yml) |
230
231
  | `--foundation-dir` | Path to foundation directory (for prerendering) |
231
232
  | `--platform <name>` | Deployment platform (e.g., `vercel`) for platform-specific output |
232
233
 
@@ -242,16 +243,26 @@ uniweb build --target foundation
242
243
  # Explicitly build as site
243
244
  uniweb build --target site
244
245
 
245
- # Build site with pre-rendering (SSG)
246
+ # Build site with pre-rendering (SSG) - force on
246
247
  uniweb build --prerender
247
248
 
249
+ # Skip pre-rendering even if enabled in site.yml
250
+ uniweb build --no-prerender
251
+
248
252
  # Build for Vercel deployment
249
253
  uniweb build --platform vercel
250
254
  ```
251
255
 
252
256
  ### Pre-rendering (SSG)
253
257
 
254
- The `--prerender` flag generates static HTML for each page at build time. This is useful for:
258
+ Pre-rendering generates static HTML for each page at build time. Enable it in `site.yml`:
259
+
260
+ ```yaml
261
+ build:
262
+ prerender: true
263
+ ```
264
+
265
+ Or use the `--prerender` flag to force it on (or `--no-prerender` to skip it). This is useful for:
255
266
 
256
267
  - **SEO**: Search engines see fully rendered content immediately
257
268
  - **Performance**: First contentful paint is instant (no JavaScript required)
@@ -275,11 +286,11 @@ The pre-rendered HTML includes a `<script id="__SITE_CONTENT__">` tag with the f
275
286
  **Usage:**
276
287
 
277
288
  ```bash
278
- # From site directory
289
+ # From site directory (with build.prerender: true in site.yml)
279
290
  cd site
280
- pnpm build:ssg
291
+ pnpm build
281
292
 
282
- # Or from workspace root
293
+ # Or force pre-rendering via CLI flag
283
294
  cd site && uniweb build --prerender
284
295
  ```
285
296
 
@@ -300,7 +311,7 @@ my-project/
300
311
  │ ├── vite.config.js # 3-line config
301
312
  │ ├── index.html
302
313
  │ ├── site.yml # Site configuration (foundation, title, i18n)
303
- │ ├── main.js # 1-line entry point
314
+ │ ├── main.js # Entry point (~6 lines)
304
315
  │ ├── pages/ # Content pages (file-based routing)
305
316
  │ │ └── home/
306
317
  │ │ ├── page.yml
@@ -311,10 +322,9 @@ my-project/
311
322
  ├── package.json
312
323
  ├── vite.config.js # 3-line config
313
324
  └── src/
314
- ├── index.js # Component exports
315
- ├── entry-runtime.js # Runtime entry (imports styles + index)
316
325
  ├── styles.css # Tailwind CSS v4
317
326
  ├── meta.js # Foundation metadata
327
+ ├── runtime.js # (optional) Custom Layout, props
318
328
  └── components/
319
329
  └── Section/
320
330
  ├── index.jsx
@@ -343,7 +353,7 @@ my-workspace/
343
353
  │ │ ├── package.json
344
354
  │ │ ├── vite.config.js # 3-line config
345
355
  │ │ ├── site.yml
346
- │ │ ├── main.js # 1-line entry point
356
+ │ │ ├── main.js # Entry point (~6 lines)
347
357
  │ │ └── pages/
348
358
  │ └── docs/ # Documentation site
349
359
 
@@ -472,8 +482,7 @@ The `defineFoundationConfig()` function handles all Vite configuration for found
472
482
  import { defineFoundationConfig } from "@uniweb/build";
473
483
 
474
484
  export default defineFoundationConfig({
475
- // All options are optional
476
- entry: "src/entry-runtime.js", // Entry point path
485
+ // All options are optional - entry is auto-generated
477
486
  fileName: "foundation", // Output file name
478
487
  externals: [], // Additional packages to externalize
479
488
  includeDefaultExternals: true, // Include react, @uniweb/core, etc.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "uniweb",
3
- "version": "0.2.29",
3
+ "version": "0.2.31",
4
4
  "description": "Create structured Vite + React sites with content/code separation",
5
5
  "type": "module",
6
6
  "bin": {
@@ -36,9 +36,9 @@
36
36
  "js-yaml": "^4.1.0",
37
37
  "prompts": "^2.4.2",
38
38
  "tar": "^7.0.0",
39
- "@uniweb/build": "0.1.13",
40
- "@uniweb/core": "0.1.6",
39
+ "@uniweb/build": "0.1.15",
40
+ "@uniweb/core": "0.1.7",
41
41
  "@uniweb/kit": "0.1.4",
42
- "@uniweb/runtime": "0.2.6"
42
+ "@uniweb/runtime": "0.2.8"
43
43
  }
44
44
  }
@@ -22,6 +22,7 @@ import {
22
22
  discoverComponents,
23
23
  processAllPreviews,
24
24
  } from '@uniweb/build'
25
+ import { readSiteConfig } from '@uniweb/build/site'
25
26
 
26
27
  // Colors for terminal output
27
28
  const colors = {
@@ -186,14 +187,8 @@ async function buildFoundation(projectDir, options = {}) {
186
187
  * - '*' → explicitly all available locales
187
188
  * - ['es', 'fr'] → only those specific locales
188
189
  */
189
- async function loadI18nConfig(projectDir) {
190
- const siteYmlPath = join(projectDir, 'site.yml')
191
- if (!existsSync(siteYmlPath)) return null
192
-
193
- const { readFile } = await import('node:fs/promises')
194
- const yaml = await import('js-yaml')
195
- const content = await readFile(siteYmlPath, 'utf-8')
196
- const config = yaml.load(content) || {}
190
+ async function loadI18nConfig(projectDir, siteConfig = null) {
191
+ const config = siteConfig || readSiteConfig(projectDir)
197
192
 
198
193
  const localesDir = config.i18n?.localesDir || 'locales'
199
194
  const localesPath = join(projectDir, localesDir)
@@ -288,7 +283,7 @@ async function generateLocalizedHtml(projectDir, i18nConfig) {
288
283
  * Build a site
289
284
  */
290
285
  async function buildSite(projectDir, options = {}) {
291
- const { prerender = false, foundationDir } = options
286
+ const { prerender = false, foundationDir, siteConfig = null } = options
292
287
 
293
288
  info('Building site...')
294
289
 
@@ -298,7 +293,7 @@ async function buildSite(projectDir, options = {}) {
298
293
  success('Site build complete')
299
294
 
300
295
  // Check for i18n configuration
301
- const i18nConfig = await loadI18nConfig(projectDir)
296
+ const i18nConfig = await loadI18nConfig(projectDir, siteConfig)
302
297
 
303
298
  if (i18nConfig && i18nConfig.locales.length > 0) {
304
299
  log('')
@@ -378,8 +373,9 @@ export async function build(args = []) {
378
373
  }
379
374
  }
380
375
 
381
- // Check for --prerender flag (SSG)
382
- const prerender = args.includes('--prerender')
376
+ // Check for --prerender / --no-prerender flags
377
+ const prerenderFlag = args.includes('--prerender')
378
+ const noPrerenderFlag = args.includes('--no-prerender')
383
379
 
384
380
  // Check for --foundation-dir flag (for prerendering)
385
381
  let foundationDir = null
@@ -401,9 +397,9 @@ export async function build(args = []) {
401
397
  info(`Detected project type: ${targetType}`)
402
398
  }
403
399
 
404
- // Validate prerender is only used with site target
405
- if (prerender && targetType !== 'site') {
406
- error('--prerender can only be used with site builds')
400
+ // Validate prerender flags are only used with site target
401
+ if ((prerenderFlag || noPrerenderFlag) && targetType !== 'site') {
402
+ error('--prerender/--no-prerender can only be used with site builds')
407
403
  process.exit(1)
408
404
  }
409
405
 
@@ -412,7 +408,16 @@ export async function build(args = []) {
412
408
  if (targetType === 'foundation') {
413
409
  await buildFoundation(projectDir)
414
410
  } else {
415
- await buildSite(projectDir, { prerender, foundationDir })
411
+ // For sites, read config to determine prerender default
412
+ const siteConfig = readSiteConfig(projectDir)
413
+ const configPrerender = siteConfig.build?.prerender === true
414
+
415
+ // CLI flags override config: --prerender forces on, --no-prerender forces off
416
+ let prerender = configPrerender
417
+ if (prerenderFlag) prerender = true
418
+ if (noPrerenderFlag) prerender = false
419
+
420
+ await buildSite(projectDir, { prerender, foundationDir, siteConfig })
416
421
  }
417
422
  } catch (err) {
418
423
  error(err.message)
package/src/index.js CHANGED
@@ -334,10 +334,13 @@ ${colors.bright}Create Options:${colors.reset}
334
334
 
335
335
  ${colors.bright}Build Options:${colors.reset}
336
336
  --target <type> Build target (foundation, site) - auto-detected if not specified
337
- --prerender Pre-render pages to static HTML (SSG) - site builds only
337
+ --prerender Force pre-rendering (overrides site.yml)
338
+ --no-prerender Skip pre-rendering (overrides site.yml)
338
339
  --foundation-dir Path to foundation directory (for prerendering)
339
340
  --platform <name> Deployment platform (e.g., vercel) for platform-specific output
340
341
 
342
+ Pre-rendering is enabled by default when build.prerender: true in site.yml
343
+
341
344
  ${colors.bright}Docs Options:${colors.reset}
342
345
  --output <file> Output filename (default: COMPONENTS.md)
343
346
  --from-source Read meta.js files directly instead of schema.json
@@ -364,7 +367,8 @@ ${colors.bright}Examples:${colors.reset}
364
367
  npx uniweb create my-project --template github:myorg/template
365
368
  npx uniweb build
366
369
  npx uniweb build --target foundation
367
- npx uniweb build --prerender # Build site + pre-render to static HTML
370
+ npx uniweb build # Auto-prerenders if site.yml has build.prerender: true
371
+ npx uniweb build --no-prerender # Skip prerendering even if enabled in config
368
372
  cd foundation && npx uniweb docs # Generate COMPONENTS.md
369
373
  `)
370
374
  }
@@ -40,24 +40,26 @@ cd site && pnpm build
40
40
 
41
41
  **Foundation:**
42
42
  - `foundation/vite.config.js` - 3-line config using `defineFoundationConfig()` from `@uniweb/build`
43
- - `foundation/src/entry-runtime.js` - Runtime entry point (imports styles + components)
44
- - `foundation/src/index.js` - Component exports
45
43
  - `foundation/src/styles.css` - Tailwind CSS v4 theme
46
- - `foundation/src/components/*/meta.js` - Component metadata and schema
44
+ - `foundation/src/components/*/meta.js` - Component metadata (makes component exposed)
45
+ - `foundation/src/runtime.js` - (optional) Custom Layout and foundation props
46
+ - `foundation/src/_entry.generated.js` - Auto-generated at build/dev time
47
47
 
48
48
  ## Architecture
49
49
 
50
50
  ### Foundation Package (`/foundation`)
51
51
 
52
- The **foundation** is a React component library. Each component:
52
+ The **foundation** is a React component library. Components with a `meta.js` file are **exposed** (available to content creators via `type:` in frontmatter). Exposed components:
53
53
 
54
- 1. Receives structured content parsed from markdown
55
- 2. Has configurable parameters (theme, layout, etc.)
56
- 3. Renders the content according to its design
54
+ 1. Receive structured content parsed from markdown
55
+ 2. Have configurable parameters (theme, layout, etc.)
56
+ 3. Render content according to their design
57
+
58
+ Internal components (no `meta.js`) are regular React components used within exposed components.
57
59
 
58
60
  **Key directories:**
59
61
  - `src/components/*/` - Component implementations
60
- - `src/components/*/meta.js` - Component metadata and schema
62
+ - `src/components/*/meta.js` - Component metadata (makes component exposed)
61
63
  - `src/styles.css` - Global Tailwind styles
62
64
 
63
65
  ### Site Package (`/site`)
@@ -79,9 +79,9 @@ pnpm build:all
79
79
 
80
80
  **Foundations:**
81
81
  - `foundations/*/vite.config.js` - 3-line config using `defineFoundationConfig()` from `@uniweb/build`
82
- - `foundations/*/src/entry-runtime.js` - Runtime entry point
83
82
  - `foundations/*/src/styles.css` - Tailwind CSS v4 theme
84
- - `foundations/*/src/components/*/meta.js` - Component metadata
83
+ - `foundations/*/src/components/*/meta.js` - Component metadata (makes component exposed)
84
+ - `foundations/*/src/runtime.js` - (optional) Custom Layout and foundation props
85
85
 
86
86
  ## Architecture
87
87
 
@@ -2,9 +2,9 @@
2
2
  "name": "default",
3
3
  "version": "0.1.0",
4
4
  "type": "module",
5
- "main": "./src/index.js",
5
+ "main": "./src/_entry.generated.js",
6
6
  "exports": {
7
- ".": "./src/index.js",
7
+ ".": "./src/_entry.generated.js",
8
8
  "./styles": "./src/styles.css",
9
9
  "./dist": "./dist/foundation.js",
10
10
  "./dist/styles": "./dist/assets/style.css"
@@ -6,8 +6,7 @@
6
6
  "scripts": {
7
7
  "dev": "vite",
8
8
  "dev:runtime": "VITE_FOUNDATION_MODE=runtime vite",
9
- "build": "vite build",
10
- "build:ssg": "vite build && uniweb build --prerender",
9
+ "build": "npx uniweb@latest build",
11
10
  "preview": "vite preview"
12
11
  },
13
12
  "dependencies": {
@@ -76,7 +76,7 @@ export function Hero({ content, params }) {
76
76
  export default Hero
77
77
  ```
78
78
 
79
- Each component needs a `meta.js` file defining its schema.
79
+ Exposed components (selectable via `type:` in frontmatter) need a `meta.js` file.
80
80
 
81
81
  ## Building
82
82
 
@@ -2,9 +2,9 @@
2
2
  "name": "foundation",
3
3
  "version": "0.1.0",
4
4
  "type": "module",
5
- "main": "./src/index.js",
5
+ "main": "./src/_entry.generated.js",
6
6
  "exports": {
7
- ".": "./src/index.js",
7
+ ".": "./src/_entry.generated.js",
8
8
  "./styles": "./src/styles.css",
9
9
  "./dist": "./dist/foundation.js",
10
10
  "./dist/styles": "./dist/assets/style.css"
@@ -6,8 +6,7 @@
6
6
  "scripts": {
7
7
  "dev": "vite",
8
8
  "dev:runtime": "VITE_FOUNDATION_MODE=runtime vite",
9
- "build": "vite build",
10
- "build:ssg": "vite build && uniweb build --prerender",
9
+ "build": "npx uniweb@latest build",
11
10
  "preview": "vite preview"
12
11
  },
13
12
  "dependencies": {
@@ -2,9 +2,9 @@
2
2
  "name": "foundation",
3
3
  "version": "0.1.0",
4
4
  "type": "module",
5
- "main": "./src/index.js",
5
+ "main": "./src/_entry.generated.js",
6
6
  "exports": {
7
- ".": "./src/index.js",
7
+ ".": "./src/_entry.generated.js",
8
8
  "./styles": "./src/styles.css",
9
9
  "./dist": "./dist/foundation.js",
10
10
  "./dist/styles": "./dist/assets/style.css"
@@ -6,8 +6,7 @@
6
6
  "scripts": {
7
7
  "dev": "vite",
8
8
  "dev:runtime": "VITE_FOUNDATION_MODE=runtime vite",
9
- "build": "vite build",
10
- "build:ssg": "vite build && uniweb build --prerender",
9
+ "build": "npx uniweb@latest build",
11
10
  "preview": "vite preview"
12
11
  },
13
12
  "dependencies": {
@@ -1,3 +0,0 @@
1
- import './styles.css'
2
- export * from './index.js'
3
- export { default } from './index.js'
@@ -1,3 +0,0 @@
1
- import './styles.css'
2
- export * from './index.js'
3
- export { default } from './index.js'
@@ -1,35 +0,0 @@
1
- /**
2
- * Foundation Entry Point
3
- *
4
- * Export all components from this file.
5
- * Components are discovered from src/components/{Name}/meta.js during build.
6
- */
7
-
8
- import Section from './components/Section/index.jsx'
9
-
10
- const components = {
11
- Section,
12
- }
13
-
14
- export function getComponent(name) {
15
- return components[name]
16
- }
17
-
18
- export function listComponents() {
19
- return Object.keys(components)
20
- }
21
-
22
- export function getSchema(name) {
23
- return components[name]?.schema
24
- }
25
-
26
- export function getAllSchemas() {
27
- const schemas = {}
28
- for (const [name, component] of Object.entries(components)) {
29
- if (component.schema) schemas[name] = component.schema
30
- }
31
- return schemas
32
- }
33
-
34
- export { Section }
35
- export default { getComponent, listComponents, getSchema, getAllSchemas, components }
@@ -1,3 +0,0 @@
1
- import './styles.css'
2
- export * from './index.js'
3
- export { default } from './index.js'
@@ -1,36 +0,0 @@
1
- /**
2
- * Foundation Entry Point
3
- *
4
- * Export all your template's components here.
5
- */
6
-
7
- import Hero from './components/Hero/index.jsx'
8
- import Features from './components/Features/index.jsx'
9
-
10
- const components = {
11
- Hero,
12
- Features,
13
- }
14
-
15
- export function getComponent(name) {
16
- return components[name]
17
- }
18
-
19
- export function listComponents() {
20
- return Object.keys(components)
21
- }
22
-
23
- export function getSchema(name) {
24
- return components[name]?.schema
25
- }
26
-
27
- export function getAllSchemas() {
28
- const schemas = {}
29
- for (const [name, component] of Object.entries(components)) {
30
- if (component.schema) schemas[name] = component.schema
31
- }
32
- return schemas
33
- }
34
-
35
- export { Hero, Features }
36
- export default { getComponent, listComponents, getSchema, getAllSchemas, components }