# Create a new application

This guide explains what a SvelteKit app inside this pnpm workspace needs to consume `@dg/ui`, file by file. The [boilerplate](../../../../apps/boilerplate/README.md) is the runnable source for every file named here; this page explains each one rather than copying it. Read the [workspace prerequisites](../../../../README.md#quick-start) first and run shell commands from the repository root.

## Start from the boilerplate

Copy the boilerplate's source files into a uniquely named `apps/<name>` directory, following its [copy procedure](../../../../apps/boilerplate/README.md#start-a-new-application). Domain content, routes, services and local components belong in that directory. Read the [composition guide](composition.md), then select components from the [reference index](../components/README.md).

The boilerplate is static and assumes hosting at the domain root. If the app needs a server, authentication or runtime endpoints, choose an appropriate adapter and prerender policy in that app. Do not put credentials in static routes or client-side imports. A static UI may call an independently hosted backend; it cannot keep a client-side secret.

## Package and configuration

The [package manifest](../../../../apps/boilerplate/package.json) depends on `"@dg/ui": "workspace:*"` and on the framework version ranges shared by the existing apps; keep them aligned rather than upgrading unrelated dependencies. `marked` belongs to the documentation app and is unnecessary elsewhere.

The build configuration ships with the toolkit, so an app depends only on its own directory and the package:

- [`vite.config.js`](../../../../apps/boilerplate/vite.config.js) passes the SvelteKit plugin and the adapter to `createViteConfig` from `@dg/ui/config/vite.js`. The factory configures SvelteKit with root-relative asset URLs, so error documents work at nested addresses; it also compiles custom media in every stylesheet, serves the package's fonts and sources in development and bundles `@dg/ui` during SSR. Do not copy the DS-specific documentation reload plugin.
- [`jsconfig.json`](../../../../apps/boilerplate/jsconfig.json) extends `$app/tsconfig`, which SvelteKit sync generates, and `@dg/ui/config/tsconfig.json`, which keeps type checks non-strict. Do not edit or commit generated `.svelte-kit` files.
- The manifest's `imports` field maps `#lib/*` to `./src/lib/*`, so app modules import `src/lib` files as `#lib/...`, with their file extension.
- [`playwright.config.js`](../../../../apps/boilerplate/playwright.config.js) passes the app's browser-test port to `createPlaywrightConfig` from `@dg/ui/config/playwright.js`, which starts the app's dev server on that port and runs the `*.spec.js` files in `tests/`. The manifest's `test:ui` script runs them.

The package exports these files:

| Export                   | Purpose                                                                                        |
| ------------------------ | ---------------------------------------------------------------------------------------------- |
| `@dg/ui`                 | Public Svelte components, listed in the [component index](../components/README.md).            |
| `@dg/ui/styles.css`      | Normal entry point, imported once in the root layout: tokens, then `base.css`.                 |
| `@dg/ui/tokens.css`      | Design tokens: shared values and the light and dark palettes, for explicit loading.            |
| `@dg/ui/base.css`        | Font faces, [document defaults](../foundations/document.md) and shared classes. Needs tokens.  |
| `@dg/ui/breakpoints.css` | Build-time custom media input; supplied through the shared Vite factory, not a runtime import. |
| `@dg/ui/fonts/*`         | Self-hosted fonts: Roboto, Roboto Mono and Teodor.                                             |
| `@dg/ui/logo.svg`        | Gallery mark for asset imports; the favicon of every gallery app.                              |
| `@dg/ui/config/*`        | The Vite, TypeScript and Playwright configuration above.                                       |

Component imports load only their scoped CSS; the foundations come from `styles.css`.

## Document and layout

[`src/app.html`](../../../../apps/boilerplate/src/app.html) sets `<html lang>` to the audience language and needs no theme script: `Page` restores the saved [theme](../foundations/colors.md#themes) before first paint.

The [root layout](../../../../apps/boilerplate/src/routes/+layout.svelte) composes the [quick reference shell](quick-reference.md#shell) once: it imports `@dg/ui/styles.css`, sets `@dg/ui/logo.svg` as the favicon, owns the single main landmark and mounts [`Analytics`](../components/analytics.md). Routes supply sections without adding another `Page` or `Main`. Set `Page`'s `lang` to match `<html lang>`, and configure identity and navigation links for the app rather than keeping the boilerplate's example routes.

[`+layout.js`](../../../../apps/boilerplate/src/routes/+layout.js) enables prerendering. Dynamic route parameters need discoverable links or explicit prerender entries before a static build can emit them. Runtime data and integrations belong to the app; the toolkit supplies presentation, interaction and audience measurement.

## Error routes and hosting

[`+error.svelte`](../../../../apps/boilerplate/src/routes/+error.svelte) renders [`ErrorPage`](../components/error-page.md) with the error status, a title and `noindex`. The [`404/`](../../../../apps/boilerplate/src/routes/404/+page.svelte) route renders the same page without an error, with `trailingSlash = "never"`, so the static build emits one `404.html` for the host.

Static output goes to `apps/<name>/build/`. The copied `Dockerfile` and `Caddyfile` serve it with clean URLs, a real 404 status and the statistics configuration, as described in [Deployment](../../../../README.md#deployment); add app-specific routes to the Caddyfile only. After deploying, check that a nested missing URL returns 404.

## Install, run and verify

```sh
pnpm install
pnpm --filter <name> dev
```

In another terminal, run the [workspace checks](../../../../README.md#checks) and build the app:

```sh
pnpm lint
pnpm --filter <name> build
pnpm --filter <name> test:ui
pnpm --filter <name> preview
```

The workspace checks, `pnpm build` and `pnpm test:ui` discover new apps. Keep the boilerplate's [`tests/shell.spec.js`](../../../../apps/boilerplate/tests/shell.spec.js), which checks the frame every app shares, adapted to the app's labels and navigation link, and add the app's browser tests beside it.

Then perform the [rendered check](../guides/accessibility.md#rendered-check) on the running app.

Finish with an app README covering purpose, routes, commands, content locations and hosting, and a local AGENTS.md only for app-specific instructions; link to this reference instead of repeating toolkit APIs. Add the application to the workspace README's app table and keep the lockfile update from installation.
