# Page Router

The Page Router handles *page-specific* code execution, and is defined in `routes.ts`.

## Automatic Route Discovery (v2.0+)

**New in v2.0:** Pages are automatically discovered using the `@page` decorator. No manual route registration needed!

### Using the @page Decorator

Simply decorate your page class with `@page` to auto-register it:

```typescript
import { PageBase, page } from "@sygnal/sse-core";

@page('/')
export class HomePage extends PageBase {
  protected onPrepare(): void {
    console.log('Home page preparing...');
  }

  protected async onLoad(): Promise<void> {
    console.log('Home page loaded');
  }
}
```

### Wildcard Routes

Use `*` for dynamic paths like CMS collections:

```typescript
import { PageBase, page } from "@sygnal/sse-core";

@page('/blog/*')  // Matches /blog/post-1, /blog/post-2, etc.
export class BlogPage extends PageBase {
  protected async onLoad(): Promise<void> {
    // Access CMS item slug automatically
    console.log('Item slug:', this.pageInfo.itemSlug);
  }
}
```

### Multiple Routes Per Page

Stack multiple `@page` decorators to handle multiple routes with one class:

```typescript
import { PageBase, page } from "@sygnal/sse-core";

@page('/about')
@page('/about-us')
@page('/team')
export class AboutPage extends PageBase {
  protected async onLoad(): Promise<void> {
    // Check which route was accessed
    console.log('Current path:', this.pageInfo.path);
  }
}
```

### Route Registration

In `routes.ts`, import your pages to trigger the decorators, then use `getAllPages()`:

```typescript
import { RouteDispatcher, getAllPages } from "@sygnal/sse-core";
import { Site } from "./site";

// Import pages to trigger @page decorators
import "./pages/home";
import "./pages/blog";
import "./pages/about";

export const routeDispatcher = (): RouteDispatcher => {
    const dispatcher = new RouteDispatcher(Site);
    dispatcher.routes = getAllPages();  // Auto-populated!
    return dispatcher;
}
```

## Manual Route Registration (Legacy)

You can still manually register routes if needed:

```typescript
import { RouteDispatcher } from "@sygnal/sse-core";
import { Site } from "./site";
import { HomePage } from "./pages/home";
import { BlogPage } from "./pages/blog";

export const routeDispatcher = (): RouteDispatcher => {
    const dispatcher = new RouteDispatcher(Site);
    dispatcher.routes = {
        '/': HomePage,
        '/blog/*': BlogPage,
    };
    return dispatcher;
}
```

## How this Works

* Site code will be executed first.
* A visit to the home page at `/` will execute the code in our `HomePage` class.
* A visit to any blog page, e.g. `/blog/2024-in-review` or `/blog/ai-futures-2025` will match our `/blog/*` route and execute the code in our `BlogPage` class.
* A visit to any other page, such as `/about` will execute nothing, because there is no route defined for it.
* A visit to `/blog` by itself, which might be a blog directory page, will execute nothing, because it does not match any patterns.
  * If you wanted `/blog` to also execute your `BlogPage` code, you could simply add another route for ``'/blog`: BlogPage`` .
* Each route can execute only one Page class.
* Each route must be unique, but you can add as many routes as you like.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://engine.sygnal.com/usage/page-router.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
