uniweb 1.20.2 → 1.20.4

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.
@@ -1,87 +1,169 @@
1
1
  # {{projectName}}
2
2
 
3
- A website built with [Uniweb](https://github.com/uniweb/cli) — a component web platform that separates content from code.
3
+ A website made with [Uniweb](https://uniweb.io): an open-source React framework and a connected
4
+ visual authoring platform.
4
5
 
5
- {{> quick-start}}
6
+ **Developers define the vocabulary. Authors compose with it. Uniweb keeps both sides in sync.**
6
7
 
7
- ## Project Structure
8
+ This project and the Uniweb app are two interfaces to the same website. Here, in code and git,
9
+ you build its **foundation**: React components, called section types, and the schemas of its
10
+ structured content. In the app, authors compose pages from those section types and manage records
11
+ through those schemas: visually, with live previews, and with no markdown, YAML or git to learn.
12
+ You build the components. Uniweb builds the authoring experience.
13
+ {{#if cloned}}
8
14
 
15
+ This project was cloned from a site in the Uniweb app (`uniweb clone`), so it is already in sync
16
+ with it. Its foundation is a registered one, not a folder of this project.
17
+ {{/if}}
18
+
19
+ ## Quick start
20
+
21
+ {{#if packages.length}}
22
+ ```bash
23
+ pnpm install
24
+ pnpm dev # prints the address it serves the site at
9
25
  ```
10
- {{projectName}}/
11
- ├── src/ # Foundation package (the site's source code; pkg name: src)
12
- │ ├── sections/ # Section types (selectable by content authors)
13
- │ ├── styles.css # Tailwind CSS v4 theme
14
- │ ├── main.js # Foundation declarations (name, vars, defaultLayout)
15
- │ └── vite.config.js # defineFoundationConfig()
16
- │
17
- ├── site/ # Content (markdown)
18
- │ ├── pages/ # Content pages
19
- │ │ └── home/
20
- │ │ ├── page.yml
21
- │ │ └── 1-welcome.md
22
- │ ├── site.yml # Site configuration (foundation: src)
23
- │ └── vite.config.js # defineSiteConfig()
24
- │
25
- └── AGENTS.md # Developer guide (human + AI)
26
+
27
+ Edit a page or a section type and the page updates as you save. With npm, use `npm install`,
28
+ `npm run dev` and `npx uniweb`.
29
+ {{else}}
30
+ This workspace started empty. Add a foundation and a site, then run them:
31
+
32
+ ```bash
33
+ npx uniweb add project <name> # a foundation in <name>/src, a site in <name>/site
34
+ pnpm install
35
+ pnpm uniweb dev # prints the address it serves the site at
26
36
  ```
37
+ {{/if}}
27
38
 
28
- A site is pure content. A foundation is the site's source code — that's why it lives in `src/`.
39
+ ## What's here
29
40
 
30
- ## Content Authoring
41
+ | Folder | What it holds |
42
+ |---|---|
43
+ {{#each packages}}
44
+ | `{{path}}/` | {{#if foundation}}a foundation: section types in `sections/`, written in React, and any data schemas in `schemas/`{{/if}}{{#if extension}}an extension: more section types, loaded beside a foundation{{/if}}{{#if site}}a site: its pages in `pages/`, with `site.yml` and `theme.yml`{{/if}} |
45
+ {{/each}}
46
+ | `AGENTS.md` | the manual for this project and its version of Uniweb, for you and for AI agents |
31
47
 
32
- Content lives in markdown files under `site/pages/`:
48
+ Each markdown file in a site's `pages/` is one section of a page. Its frontmatter names a
49
+ section type, and the component receives the content already parsed. For example:
33
50
 
34
51
  ```markdown
35
52
  ---
36
- type: Section
37
- theme: light
53
+ type: Hero
38
54
  ---
39
55
 
40
- # Welcome
41
-
42
- Your content here.
56
+ # Build something great
43
57
 
44
- [Call to Action](#)
58
+ Edit this text, not the component.
45
59
  ```
46
60
 
47
- {{> adding-pages}}
48
-
49
- ## Component Development
50
-
51
- Section types live in `src/sections/`. Each is a folder with an `index.jsx` and a `meta.js`:
52
-
53
61
  ```jsx
54
- // src/sections/Hero/index.jsx
62
+ // sections/Hero/index.jsx
55
63
  import { H1, P } from '@uniweb/kit'
56
64
 
57
65
  export default function Hero({ content }) {
58
- const { title, paragraphs = [] } = content || {}
59
-
60
66
  return (
61
- <div className="max-w-4xl mx-auto px-6">
62
- <H1 text={title} className="text-heading text-4xl font-bold" />
63
- <P text={paragraphs} className="text-body mt-4" />
67
+ <div className="mx-auto max-w-4xl px-6">
68
+ <H1 text={content.title} className="text-4xl font-bold text-heading" />
69
+ <P text={content.paragraphs} className="mt-4 text-body" />
64
70
  </div>
65
71
  )
66
72
  }
67
73
  ```
68
74
 
69
- Components receive parsed content from markdown. Classes like `text-heading` and `text-body` are semantic tokens — the site controls their actual colors through theming, so the same component adapts to any context automatically.
75
+ `text-heading` and `text-body` are theme tokens. A site's `theme.yml` sets their colors, so one
76
+ component works in light and dark sections, and on every site that uses it.
70
77
 
71
- {{> components-docs}}
78
+ ## Connect the authoring app
72
79
 
73
- ## Building
80
+ Start with a normal project, and connect the app when you want visual authoring:
74
81
 
75
82
  ```bash
76
- # Build foundation (generates dist/foundation.js)
77
- cd foundation && pnpm build
83
+ pnpm uniweb login # sign in to your Uniweb account
84
+ pnpm uniweb sync # the first sync brings the site and its foundation into the app
85
+ ```
86
+
87
+ From then on, the CLI is the bridge between the two workflows:
88
+
89
+ | Command | What it does |
90
+ |---|---|
91
+ | `pnpm uniweb push` | sends your section types, schemas and content to the app: a draft, not live |
92
+ | `pnpm uniweb pull` | brings authors' edits into your files, as a git merge |
93
+ | `pnpm uniweb sync` | takes your teammates' commits and the authors' edits, then pushes yours |
94
+ | `pnpm uniweb publish` | pushes, then takes the site live on Uniweb hosting, a paid service |
95
+
96
+ Authors never need to think about synchronization: in the app, their changes appear live. On
97
+ your side, edits to different sections combine, and nothing overwrites an author's edit. When
98
+ the same section changed on both sides, `sync` stops at a git conflict for you to settle. Like
99
+ git, a push sends what you have committed; `--commit` commits the site's content first.
100
+
101
+ ### Structured content, editable without an admin app
102
+
103
+ A section type declares the data it shows, by schema, in its `meta.js`:
78
104
 
79
- # Build site for production
80
- cd site && pnpm build
105
+ ```js
106
+ export default {
107
+ data: {
108
+ people: '@std/person', // a standard schema, from @uniweb/schemas
109
+ events: '@/event' // this foundation's own, in schemas/event.yml
110
+ }
111
+ }
81
112
  ```
82
113
 
83
- Deploy `site/dist/` to any static host (Vercel, Netlify, Cloudflare Pages, etc.)
114
+ A standard schema needs `@uniweb/schemas` as a dependency of the foundation. In the app, authors
115
+ get forms and records for those schemas. No separate admin application is needed to make the
116
+ data editable.
117
+
118
+ ## Other ways to use it
119
+
120
+ The framework works on its own, too.
121
+
122
+ - **Content in files only.** If you manage the content yourself, the site needs no Uniweb account.
123
+ `pnpm build` makes each site's `dist/`, a static site for any host, and `pnpm uniweb deploy`
124
+ ships it to GitHub Pages, Cloudflare Pages, Netlify, Vercel or S3 + CloudFront.
125
+ - **Foundations for your clients' sites.** If the sites belong to your clients, who make and edit
126
+ them in the app, this project is where you build and test the foundation.
127
+ `pnpm uniweb register` publishes it to Uniweb for their sites.
128
+
129
+ ## Working with AI agents
130
+
131
+ A Uniweb project gives an agent a system to work within, its section types, schemas and content
132
+ conventions, instead of a blank canvas. What an agent builds here, authors can use in the app
133
+ after the next sync.
134
+
135
+ [AGENTS.md](./AGENTS.md) is written for developers and AI agents alike. Many coding agents read it
136
+ on their own when they start in this folder; point any other agent at it first.
137
+ `npx uniweb@latest update` moves the project to the latest release of Uniweb, and AGENTS.md with
138
+ it.
139
+
140
+ Some prompts to try:
141
+
142
+ **Converting an existing design:**
143
+ ```
144
+ I have a landing page design in `homepage.jsx`. Convert it into this Uniweb
145
+ project. Decompose each visual section into a section type in the foundation,
146
+ and extract all text content into markdown files in the site's pages/home/.
147
+ The final page should render identically to the original. See AGENTS.md.
148
+ ```
149
+
150
+ **Adding a section type:**
151
+ ```
152
+ Create a Pricing section type with 3-column cards. It should work in light and
153
+ dark sections. Use content.items for the pricing tiers — each item has a title,
154
+ a paragraph (the price), and a link (the call to action).
155
+ ```
156
+
157
+ **Adding a page:**
158
+ ```
159
+ Add a /contact page with a hero section and a contact details section. Reuse
160
+ the Hero section type from the homepage.
161
+ ```
84
162
 
85
- {{> ai-assistance}}
163
+ ## Learn more
86
164
 
87
- {{> learn-more}}
165
+ - [Documentation](https://uniweb.io/docs): guides and reference. For AI agents, its index is
166
+ https://uniweb.io/llms.txt
167
+ - [Uniweb app](https://uniweb.app): the visual authoring platform
168
+ - `pnpm uniweb <command> --help`: every command's options
169
+ - `pnpm uniweb doctor`: checks the project's configuration
@@ -1,77 +0,0 @@
1
- ### Adding a New Page
2
-
3
- 1. Create a folder: `site/pages/my-page/`
4
- 2. Add `page.yml`:
5
- ```yaml
6
- title: My Page
7
- ```
8
- 3. Add section files: `1-hero.md`, `2-content.md`, etc.
9
-
10
- ### Section Ordering
11
-
12
- By default, sections are discovered from `.md` files and sorted by numeric prefix (`1-`, `2-`, `3-`).
13
-
14
- **Decimal prefixes** allow inserting sections without renumbering: `2.5-` sorts between `2-` and `3-`.
15
-
16
- For explicit control, use the `sections` property in `page.yml`:
17
-
18
- ```yaml
19
- title: My Page
20
- sections:
21
- - hero
22
- - features
23
- - pricing
24
- ```
25
-
26
- This makes reordering easy (move lines) and allows commenting out sections temporarily.
27
-
28
- **Options:**
29
- - `sections: *` or omit — auto-discover and sort `.md` files by prefix (default)
30
- - `sections: [hero, features]` — explicit ordering, no prefixes needed
31
- - `sections: []` — pure route with no content sections
32
-
33
- ### Section Hierarchy (Subsections)
34
-
35
- For parent-child relationships, use the explicit array with nesting:
36
-
37
- ```yaml
38
- sections:
39
- - hero
40
- - features:
41
- - logocloud
42
- - stats
43
- - pricing
44
- ```
45
-
46
- This is clearer than prefix notation and easier to restructure.
47
-
48
- **Advanced:** Comma prefixes (`1,1-`, `1,2-`) also denote hierarchy, but explicit arrays are recommended for readability.
49
-
50
- ### Page Ordering and Index Pages
51
-
52
- Parent controls which page is the "index" for its route. The index page gets the parent's route.
53
-
54
- **In `site.yml`** (for top-level pages):
55
- ```yaml
56
- name: My Site
57
- pages: [home, about, features] # First (home) is homepage at /
58
- # Or just name the homepage:
59
- index: home
60
- ```
61
-
62
- **In `page.yml`** (for child pages):
63
- ```yaml
64
- title: Documentation
65
- pages: [getting-started, installation, config] # First is index for /docs
66
- # Or just name the index:
67
- index: getting-started
68
- ```
69
-
70
- **How it works:**
71
- - `pages: [a, b, c]` — Explicit order, first item gets parent route
72
- - `index: name` — Just set the index, auto-discover the rest
73
- - Omit both — Sort by `order` prop, lowest becomes index
74
-
75
- **Example:** If `getting-started` is the index for `/docs`:
76
- - `pages/docs/getting-started/` → route `/docs`
77
- - `pages/docs/installation/` → route `/docs/installation`
@@ -1,28 +0,0 @@
1
- ## Developer Guide
2
-
3
- [AGENTS.md](./AGENTS.md) is a comprehensive guide to building with Uniweb — content authoring, component development, theming, configuration, and the kit API. Despite the name, it's written for developers and AI assistants alike. Read it to get productive fast.
4
-
5
- ### AI Prompts
6
-
7
- AI coding assistants (Claude Code, Cursor, Copilot, etc.) read AGENTS.md automatically. Some prompts to try:
8
-
9
- **Converting an existing design:**
10
- ```
11
- I have a landing page design in `homepage.jsx`. Convert it into this Uniweb
12
- project. Decompose each visual section into a foundation component and extract
13
- all text content into markdown files in site/pages/home/. The final page
14
- should render identically to the original. See AGENTS.md for the full guide.
15
- ```
16
-
17
- **Adding a new component:**
18
- ```
19
- Create a Pricing component with 3-column cards. It should support light and
20
- dark themes. Use content.items for the pricing tiers — each item has a title,
21
- paragraph (price), and links (CTA button).
22
- ```
23
-
24
- **Adding a new page:**
25
- ```
26
- Add a /contact page with a hero section and a form section. Reuse the Hero
27
- component from the homepage. Create a new ContactForm component for the form.
28
- ```
@@ -1,13 +0,0 @@
1
- ## Component Documentation
2
-
3
- Generate up-to-date documentation for all foundation components:
4
-
5
- ```bash
6
- # From foundation directory
7
- uniweb docs
8
-
9
- # Or from site directory (auto-detects linked foundation)
10
- cd site && uniweb docs
11
- ```
12
-
13
- This creates `COMPONENTS.md` with details on each component's parameters, presets, and content elements. The documentation is generated from component `meta.js` files, so it's always current.
@@ -1,66 +0,0 @@
1
- ## Configuration Reference
2
-
3
- ### site.yml
4
-
5
- Site-wide configuration in `site/site.yml`:
6
-
7
- ```yaml
8
- name: My Site # Site name
9
- defaultLanguage: en # Default locale code
10
- foundation: foundation # Foundation package name
11
-
12
- # Page ordering (controls top-level navigation)
13
- pages: [home, about, features] # First is homepage at /
14
- # Or just name the homepage:
15
- index: home
16
-
17
- # Internationalization
18
- i18n:
19
- locales: [es, fr] # Non-default locales to build
20
- localesDir: locales # Translation files directory
21
-
22
- # Build options
23
- build:
24
- prerender: true # Enable static site generation
25
- ```
26
-
27
- ### page.yml
28
-
29
- Page-level configuration in `site/pages/[page]/page.yml`:
30
-
31
- ```yaml
32
- title: About Us # Page title (used in <title> and nav)
33
- description: Learn about us # Meta description
34
- label: About # Short nav label (optional)
35
- order: 2 # Navigation sort order
36
-
37
- # Child page ordering
38
- pages: [intro, guide, reference] # First is index for this route
39
- index: intro # Or just name the index
40
-
41
- # Navigation visibility
42
- hidden: true # Hide from all navigation
43
- hideIn: [header] # Hide from named nav areas only (header, footer, sidebar, …)
44
-
45
- # Layout overrides
46
- layout:
47
- header: false # Don't render header
48
- footer: false # Don't render footer
49
-
50
- # Section ordering
51
- sections: # Explicit section order
52
- - hero
53
- - features: # Nested = subsections
54
- - logocloud
55
- - stats
56
- - pricing
57
-
58
- # SEO
59
- seo:
60
- noindex: true
61
- image: /og-image.png
62
- changefreq: monthly
63
- priority: 0.8
64
- ```
65
-
66
- Run `uniweb docs site` or `uniweb docs page` for complete reference.
@@ -1,13 +0,0 @@
1
- ## Deployment
2
-
3
- Build and deploy the `site/dist` folder:
4
-
5
- ```bash
6
- pnpm build
7
- ```
8
-
9
- **Supported platforms:**
10
- - **Vercel**: `cd site && vercel`
11
- - **Netlify**: Build command `pnpm build`, publish `site/dist`
12
- - **GitHub Pages**: Use GitHub Actions
13
- - **Cloudflare Pages**: Connect repo, set `pnpm build` and `site/dist`
@@ -1,6 +0,0 @@
1
- ## Learn More
2
-
3
- - [AGENTS.md](./AGENTS.md) — comprehensive guide to building with Uniweb
4
- - [Uniweb Documentation](https://github.com/uniweb/docs) — full reference docs
5
- - [Uniweb CLI](https://github.com/uniweb/cli) — project scaffolding and build tools
6
- - [Tailwind CSS v4](https://tailwindcss.com)
@@ -1,8 +0,0 @@
1
- ## Quick Start
2
-
3
- ```bash
4
- pnpm install # Install dependencies
5
- pnpm dev # Start development server
6
- ```
7
-
8
- Visit `http://localhost:5173` to see your site.
@@ -1,110 +0,0 @@
1
- ## Search Functionality
2
-
3
- Uniweb sites support full-text search out of the box. Search indexes are generated automatically at build time.
4
-
5
- ### Enabling Search in Your Foundation
6
-
7
- To add search to your site, your foundation needs the **Fuse.js** library:
8
-
9
- ```bash
10
- cd foundation
11
- pnpm add fuse.js
12
- ```
13
-
14
- Then use the search helpers from `@uniweb/kit`:
15
-
16
- ```jsx
17
- import { useSearch } from '@uniweb/kit'
18
-
19
- function SearchComponent({ website }) {
20
- const { query, results, isLoading, clear } = useSearch(website)
21
-
22
- return (
23
- <div>
24
- <input
25
- type="search"
26
- placeholder="Search..."
27
- onChange={e => query(e.target.value)}
28
- />
29
- {isLoading && <span>Searching...</span>}
30
- <ul>
31
- {results.map(result => (
32
- <li key={result.id}>
33
- <a href={result.href}>{result.title}</a>
34
- <p dangerouslySetInnerHTML=\{{ __html: result.snippetHtml }} />
35
- </li>
36
- ))}
37
- </ul>
38
- </div>
39
- )
40
- }
41
- ```
42
-
43
- ### Search Configuration
44
-
45
- Search is enabled by default. To customize, add to `site/site.yml`:
46
-
47
- ```yaml
48
- search:
49
- enabled: true
50
- exclude:
51
- routes: [/admin, /private] # Don't index these routes
52
- components: [Debug] # Don't index these component types
53
- ```
54
-
55
- ### How It Works
56
-
57
- 1. **Build time**: Uniweb extracts text from all pages and sections
58
- 2. **Output**: A `search-index.json` file is generated in `dist/`
59
- 3. **Runtime**: Components fetch and search the index client-side
60
- 4. **Multi-locale**: Each locale gets its own search index
61
-
62
- ### Search API
63
-
64
- The `website` object provides these methods:
65
-
66
- ```javascript
67
- // Check if search is available
68
- website.isSearchEnabled() // Returns boolean
69
-
70
- // Get the URL for the search index
71
- website.getSearchIndexUrl() // "/search-index.json" or "/es/search-index.json"
72
-
73
- // Get full search configuration
74
- website.getSearchConfig() // { enabled, indexUrl, locale, include, exclude }
75
- ```
76
-
77
- ### Search Result Format
78
-
79
- Results from `useSearch()` include:
80
-
81
- | Field | Description |
82
- |-------|-------------|
83
- | `id` | Unique result identifier |
84
- | `type` | `"page"` or `"section"` |
85
- | `route` | Page route |
86
- | `href` | Full link including anchor |
87
- | `title` | Result title |
88
- | `pageTitle` | Parent page title (for sections) |
89
- | `snippetHtml` | Excerpt with `<mark>` highlighted matches |
90
- | `snippetText` | Plain text excerpt |
91
-
92
- ### Without @uniweb/kit
93
-
94
- If you prefer not to use the kit helpers, you can fetch the index directly:
95
-
96
- ```javascript
97
- // Fetch the search index
98
- const response = await fetch(website.getSearchIndexUrl())
99
- const index = await response.json()
100
-
101
- // Use with Fuse.js directly
102
- import Fuse from 'fuse.js'
103
- const fuse = new Fuse(index.entries, {
104
- keys: ['title', 'content'],
105
- threshold: 0.35,
106
- includeMatches: true
107
- })
108
-
109
- const results = fuse.search('your query')
110
- ```