# Router app

Source: https://signy.dev/examples/router-app/

Pages, links and a route parameter, with the router in hash mode.

The router runs in hash mode, so the app works from any static host and inside the frame below. Each page is a component, and the layout renders the current one in an `Outlet`.

## Preview

[Open the page on its own](https://signy.dev/examples/router-app/demo/index.html.md)

## Code

Save it as an `.html` file and open it in a browser. It loads Signy and Iris CSS from the CDN, so there is nothing to install or build.

**Show the full page**

```html
<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="color-scheme" content="light dark">
    <title>Router app - Signy example</title>
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/iriscss@1/dist/iris.min.css">
    <script src="https://cdn.jsdelivr.net/npm/signy@1/dist/signy.global.min.js"></script>
  </head>
  <body>
    <div id="app"></div>

    <script>
      const { Component, application, html, router, Link, Outlet, For, Show, useParams, useRouter } = Signy;

      const PEOPLE = [
        { id: "ada", name: "Ada Lovelace", known: "the first published computer program" },
        { id: "grace", name: "Grace Hopper", known: "the first compiler" },
        { id: "alan", name: "Alan Turing", known: "the Turing machine" },
      ];

      class Home extends Component {
        render() {
          return html`
            <section class="hero">
              <h1>Computing pioneers</h1>
              <p>A small app with a router in hash mode, so it works on any static host.</p>
              <${Link} to="/people" class="primary" role="button">Meet them</${Link}>
            </section>
          `;
        }
      }

      class People extends Component {
        render() {
          return html`
            <h1>People</h1>
            <div class="grid">
              ${For({
                each: PEOPLE,
                keyBy: "id",
                children: (person) => html`
                  <article class="card">
                    <h2>${person.name}</h2>
                    <${Link} to=${`/people/${person.id}`}>Read more</${Link}>
                  </article>
                `,
              })}
            </div>
          `;
        }
      }

      class Person extends Component {
        render() {
          const params = useParams(this);
          const nav = useRouter(this);
          const person = () => PEOPLE.find((p) => p.id === params.value.id);
          return html`
            ${Show({
              when: person,
              fallback: html`<p>No one with that name.</p>`,
              children: (found) => html`
                <h1>${found.name}</h1>
                <p>Known for ${found.known}.</p>
              `,
            })}
            <button class="secondary outlined" onClick=${() => nav.back()}>Back</button>
          `;
        }
      }

      class NotFound extends Component {
        render() {
          return html`
            <h1>Page not found</h1>
            <${Link} to="/">Go home</${Link}>
          `;
        }
      }

      class Layout extends Component {
        render() {
          return html`
            <header class="navbar">
              <nav class="container" aria-label="Main">
                <ul>
                  <li><${Link} to="/"><strong>Pioneers</strong></${Link}></li>
                </ul>
                <ul>
                  <li><${Link} to="/people">People</${Link}></li>
                  <li><${Link} to="/missing">Broken link</${Link}></li>
                </ul>
              </nav>
            </header>
            <main class="container">
              <${Outlet} />
            </main>
          `;
        }
      }

      const appRouter = router({
        mode: "hash",
        routes: [
          { path: "/", component: Home },
          { path: "/people", component: People },
          { path: "/people/:id", component: Person },
          { path: "*", component: NotFound },
        ],
      });

      application(Layout).use(appRouter).mount("#app");
    </script>
  </body>
</html>

```

## What it uses

- [Routes](https://signy.dev/documentation/1/router/routes/index.html.md), [Link and useRouter()](https://signy.dev/documentation/1/router/navigation/index.html.md), [useParams()](https://signy.dev/documentation/1/router/params-and-query/index.html.md) and a `*` route for the not found page
