name: ng-add-demo description: Add a new demo to any module under demos/. Registers it in db.json, generates the component, adds the route, adds the markdown renderer, and creates an empty guide. Triggers on: add demo, create demo, new demo, register demo.
Inputs
Collect before starting:
- Module path — e.g.
demos/03-signals/ng-signals - Slug — kebab-case, used for the route, folder, and markdown filename. E.g.
linked-signal - Title — shown in the sidenav. E.g.
Linked Signal - Next id — read
db.json → demos, takemax(id) + 1
Steps
1. Register in db.json
{ "id": <next-id>, "url": "<slug>", "title": "<Title>" }
2. Generate the component
cd <module-path>
npx ng generate component demos/samples/<slug> --change-detection OnPush --inline-style --skip-tests
3. Set up the template
Replace the generated template with:
<app-markdown-renderer [md]="'<slug>'" />
Add to the component's imports array:
import { MarkdownRendererComponent } from '../../../shared/markdown-renderer/markdown-renderer.component';
4. Create the markdown guide
Create public/markdown/<slug>.md — must not be empty or the renderer will 404:
- Guide coming soon.
5. Add the route
In src/app/demos/demo.routes.ts:
import { <PascalSlug>Component } from './samples/<slug>/<slug>.component';
{ path: '<slug>', component: <PascalSlug>Component },
6. Verify
npx ng build --configuration development 2>&1 | Select-Object -Last 10
Paths at a glance
| Artifact | Path |
|---|---|
| Component | src/app/demos/samples/<slug>/ |
| Route | src/app/demos/demo.routes.ts |
| Guide | public/markdown/<slug>.md |
| Registration | db.json → demos |
Example — linked-signal in demos/03-signals/ng-signals
npx ng generate component demos/samples/linked-signal --change-detection OnPush --inline-style --skip-tests
db.json: { "id": 13, "url": "linked-signal", "title": "Linked Signal" }
demo.routes.ts: { path: 'linked-signal', component: LinkedSignalComponent }
public/markdown/linked-signal.md:
- Examine `linked-signal.component.ts` and its use of `linkedSignal` to create a writable signal that resets whenever its source changes
Steps
Step 1 — Register in db.json
Append to the demos array in <module>/db.json:
{
"id": <next-id>,
"url": "<slug>",
"title": "<Title>"
}
Step 2 — Generate the component
Run the Angular CLI from the module root:
cd <module-path>
npx ng generate component demos/samples/<slug> --change-detection OnPush --inline-style --skip-tests
Flags:
--change-detection OnPush— required by project conventions--inline-style— styles are minimal for demo components; avoids an extra file--skip-tests— spec files are written separately when needed
Step 3 — Add MarkdownRendererComponent to the template
Replace the generated template content with:
<app-markdown-renderer [md]="'<slug>'" />
Add MarkdownRendererComponent to the component's imports array:
import { MarkdownRendererComponent } from '../../../shared/markdown-renderer/markdown-renderer.component';
@Component({
selector: 'app-<slug>',
imports: [MarkdownRendererComponent],
templateUrl: './<slug>.component.html',
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class <PascalSlug>Component {}
The path to
MarkdownRendererComponentis relative — adjust../depth if the component is nested differently.
Step 4 — Create the markdown guide
Create <module-path>/public/markdown/<slug>.md with a minimal placeholder:
## <Title>
> Guide coming soon.
Do not leave the file empty — the markdown renderer will show a 404 error.
Step 5 — Register the route
Add a child route to <module-path>/src/app/demos/demo.routes.ts:
import { <PascalSlug>Component } from './samples/<slug>/<slug>.component';
// inside the children array:
{ path: '<slug>', component: <PascalSlug>Component },
Keep imports alphabetically sorted and routes in the same order as db.json.
Step 6 — Verify the build
cd <module-path>
npx ng build --configuration development 2>&1 | Select-Object -Last 15
Fix any TypeScript errors before finishing.
Path conventions
| Artifact | Location |
|---|---|
| Component | src/app/demos/samples/<slug>/ |
| Route registration | src/app/demos/demo.routes.ts |
| Markdown guide | public/markdown/<slug>.md |
| db.json | <module-root>/db.json |
Example
Adding linked-signal to demos/03-signals/ng-signals:
cd demos/03-signals/ng-signals
npx ng generate component demos/samples/linked-signal --change-detection OnPush --inline-style --skip-tests
db.json entry:
{ "id": 13, "url": "linked-signal", "title": "Linked Signal" }
demo.routes.ts addition:
import { LinkedSignalComponent } from './samples/linked-signal/linked-signal.component';
// ...
{ path: 'linked-signal', component: LinkedSignalComponent },
public/markdown/linked-signal.md:
## Linked Signal
`linkedSignal` creates a writable signal whose default value is derived from another signal.
It resets automatically whenever the source signal changes.