gui/docs/ref/wails-v3/contributing/template-system.mdx

223 lines
5.9 KiB
Text
Raw Permalink Normal View History

---
title: Template System
description: How Wails v3 scaffolds new projects, how templates are organised, and how to build your own.
sidebar:
order: 7
---
Wails ships with a **template system** that lets `wails3 init` produce a ready-to-run
project for **any** modern frontend stack (React, Svelte, Vue, Solid, Vanilla
JS …).
This page covers:
1. Template directory layout
2. How the CLI chooses & renders templates
3. Creating a new template step-by-step
4. Updating or overriding existing templates
5. Troubleshooting and best practices
---
## 1. Where Templates Live
```
v3/
└── internal/templates/
├── _common/ # Files copied into EVERY project (main.go, .gitignore)
├── base/ # Backend-only “plain Go” template
├── react/ # React + Vite
├── react-ts/
├── svelte/
├── vue/
├── ... (others)
└── templates.go # Registry + helper functions
```
* **`_common/`** universal boilerplate (Go modules, Taskfile, README stub,
VS Code settings).
* **Framework folders** contain **frontend/** and any stack-specific config.
* Folder names match the **template ID** you pass to the CLI
(`wails3 init -t react-ts`).
> The whole directory is compiled into the CLI binary via `go:embed`, so users
> can scaffold projects offline.
---
## 2. How `wails3 init` Uses Templates
Call chain:
```
cmd/wails3/init.go
internal/commands/init.go ← parses flags, target dir
internal/templates.Load() ← templates.go
Template.CopyTo(dest) ← filesystem copy + text substitutions
```
### Substitutions
Placeholders wrapped in `{{ }}` are replaced at copy time:
| Placeholder | Example | Source |
|-------------|---------|--------|
| `{{ProjectName}}` | `myapp` | CLI flag/dir name |
| `{{ModulePath}}` | `github.com/me/myapp` | if `--module` provided |
| `{{WailsVersion}}`| `v3.0.0` | compiled constant |
You can add **any** placeholder; just ensure it gets a value in
`internal/commands/init.go`.
### Post-Copy Hooks
Each template may ship a **Taskfile** with a `deps` task.
After copy, the CLI runs:
```
task --taskfile Taskfile.yml deps
```
Typical work:
* `go mod tidy`
* `npm install`
* git init & initial commit (optional)
Hook behaviour defined in `_common/Taskfile.yml` but override-able per template.
---
## 3. Creating a New Template
> Example: Add **Qwik-TS** template
### 3.1 Folder & ID
```
internal/templates/qwik-ts/
```
The folder name = template ID. Keep it **kebab-case**.
### 3.2 Minimal File Set
```
qwik-ts/
├── README.md # Shown in CLI with -list
├── frontend/ # Your web project
│ ├── src/
│ ├── package.json
│ └── vite.config.ts
├── Taskfile.yml # deps & dev tasks
└── go/ # Optional extra Go files
```
Start by copying `react-ts` and pruning files.
### 3.3 Update Placeholders
Search/replace:
* `myapp` → `{{ProjectName}}`
* `github.com/you/myapp` → `{{ModulePath}}`
### 3.4 Register (optional)
If the folder exists, **templates.go auto-detects it** via `embed`.
Only add explicit code if you need **custom validation**:
```go
func (t *Template) Validate() error {
// check Node ≥ 20 for this template
}
```
### 3.5 Test
```bash
wails3 init -n demo -t qwik-ts
cd demo
wails3 dev
```
Ensure:
* Dev server starts
* `wailsjs` bindings generate
* Hot-reload works
---
## 4. Modifying Existing Templates
1. Edit files under `internal/templates/<id>/`.
2. Run `go generate ./v3/...` **or** just `go run ./v3/cmd/wails3 help`; the
embed directive recompiles automatically.
3. Bump any **dependency versions** in `frontend/package.json` & `Taskfile.yml`.
4. Update `README.md` inside the template — users see it via
`wails3 init -t react --help`.
### Common Tweaks
| Task | Where |
|------|-------|
| Change dev server port | `frontend/Taskfile.yml` (`vite dev --port {{DevPort}}`) |
| Add environment variables | same Taskfile or `.env` |
| Replace JS package manager | Switch `npm` → `pnpm` in Taskfile |
---
## 5. Template Authoring Tips
* **Keep frontend generic** avoid referencing Wails-specific globals; runtime
is injected automatically.
* **No compiled artefacts** exclude `node_modules`, `dist`, `.DS_Store` via
`.tmplignore`.
* **Document prerequisites** Node version, extra CLI tools, etc.
* **Avoid breaking changes** create a *new* template ID if overhaul is big.
---
## 6. Troubleshooting
| Symptom | Cause | Fix |
|---------|-------|-----|
| `unknown template id` | Folder name mismatch | Check `wails3 init -list` |
| Placeholders not replaced | Missing entry in `Data` map | Edit `internal/commands/init.go` |
| Dev server opens blank page | Wrong `DevPort` env | Ensure Taskfile echoes port to stdout |
| Frontend fails to build in prod | Forgotten vite `base` path | Set `base: "./"` in `vite.config.ts` |
Add `--verbose` to `wails3 init` to print every copied file and substitution.
---
## 7. Key Source File Map
| File | Responsibility |
|------|----------------|
| `internal/templates/templates.go` | Embeds template FS, returns `[]Template` |
| `internal/templates/<id>/**` | Actual template content |
| `internal/commands/init.go` | CLI glue: picks template, fills placeholders |
| `internal/commands/generate_template.go` | Utility to *export* a live project back into a template (handy for updates) |
---
## 8. Recap
* Templates live in **`internal/templates/`** and are baked into the CLI.
* `wails3 init -t <id>` copies `_common` + selected template, performs
substitutions, then runs a **deps** Taskfile hook.
* Creating a template is as simple as **making a folder**, adding files, and
using placeholders.
* The system is **extensible** and **self-contained** — perfect for sharing
custom stacks with your team or the community.
Happy templating!