A prototype using the GOV.UK Design System.
This project uses Svelte, a superset of HTML, making working with it feel familiar if you've done any web development before. It's built with Sapper for mostly effortless routing, server-side rendering, and static site generation. If you don't use any dynamic server-side logic, you don't need to run a server!
You can create a new project as a GitHub repository from this template.
Click on "Use this template" in this repository on GitHub to create a new project repository initialized by the template.
degit
is a scaffolding tool that lets
you create a clean directory from a repository.
To create a new project locally, you can run
npx degit "github:erbridge/govuk-prototype-template#main" my-app
Replace my-app
with the path where you wish to create the project.
Search the entire project for TODO
s and resolve them to set this template up
for your own project.
Install the dependencies:
npm install
Build the dependencies:
npm run build
Run the project in development mode:
npm run dev
This starts the development server on localhost:3000.
While running in development mode, you can make changes to most of the project and have it update live in your browser without restarting the process.
If you need help working with Sapper or Svelte, consult their documentation.
This project supports TypeScript as an optional feature. If you don't want to write TypeScript, you can still write plain, untyped JavaScript as normal.
To opt in to TypeScript, add lang="ts"
to your <script>
tags in Svelte
files, and use the .ts
file extensions for modules.
@sapper
dependencies are resolved through src/node_modules/@sapper
, which is
created during the build. You, therefore, need to run or build the project once
to avoid warnings about missing dependencies.
This project supports SCSS as an optional feature. If you don't want to write SCSS, you can still write plain CSS.
To opt in to SCSS, add lang="scss"
to your <style>
tags in Svelte files.
Sapper expects to find two directories in the root of your project — src
and
static
.
The src
directory contains the entry points for your app — client.ts
,
server.ts
and (optionally) a service-worker.ts
— along with a
template.html
file and a routes
directory.
This is the heart of your application. There are two kinds of routes — pages, and server routes.
Pages are Svelte components written in .svelte
files. When a user first
visits the application, they are served a server-rendered version of the route
in question, plus some JavaScript that "hydrates" the page and initializes a
client-side router. From that point forward, navigating to other pages is
handled entirely on the client for a fast, app-like feel. (Sapper preloads and
caches the code for these subsequent pages so navigation is instantaneous.)
Server routes are modules written in .js
or .ts
files that export
functions corresponding to HTTP methods. Each function receives Express
request
and response
objects as arguments, plus a next
function. This is
useful for creating a JSON API, for example.
There are three rules for naming the files that define your routes:
- A file called
src/routes/about.svelte
corresponds to the/about
route. A file calledsrc/routes/blog/[slug].svelte
corresponds to the/blog/:slug
route, in which caseparams.slug
is available to the route - The file
src/routes/index.svelte
(orsrc/routes/index.ts
) corresponds to the root of your app.src/routes/about/index.svelte
is treated the same assrc/routes/about.svelte
. - Files and directories with a leading underscore do not create routes. This
allows you to colocate helper modules and components with the routes that
depend on them — for example you could have a file called
src/routes/_helpers/datetime.ts
and it would not create a/_helpers/datetime
route.
Images added to src/node_modules/images
can be imported into your code using
import "images/<filename>"
. They are given a dynamically generated filename
containing a hash, allowing for efficient caching and serving the images on a
CDN.
This directory is managed by Sapper and generated when building. It contains all
the code you import from @sapper
modules.
The static
directory contains static assets that should be served
publicly. Files in this directory are available directly under the root URL, eg
static/image.jpg
is available as /image.jpg
.
The default service-worker.ts
will preload and cache
these files, by retrieving a list of files
from the generated manifest:
import { files } from "@sapper/service-worker";
If you have static files you don't want to cache, you should exclude them from
this list after importing it (and before passing it to cache.addAll
).
Static files are served using sirv.
Sapper uses rollup.js to provide code-splitting and dynamic imports, as well as compiling your Svelte components. You can edit the configuration files to add whatever plugins you'd like.
To start a production version of your app, run npm run build && npm start
.
This disables live reloading and activates the appropriate bundler plugins.
If you're not using a database, auth, or any other dynamic, server-side code,
you can probably generate and use a static site. Run npm run export
to
generate the site. The result will be available from __sapper__/export
, and
you can run it with npx serve __sapper__/export
or deploy it to your choice of
static site host.
Due to how Sapper creates exports, you need to either ensure all of your pages
are reachable via links from your index page, or set the
--entry
flag in the export
script in package.json
.
For more information, see the Sapper documentation on exporting.
When using Svelte components installed from npm, such as @sveltejs/svelte-virtual-list, Svelte needs the original component source (rather than any precompiled JavaScript that ships with the component). This allows the component to be rendered server-side, and also keeps your client-side app smaller.
Because of that, it's essential that the bundler doesn't treat the package as an
external dependency. You can either modify the external
option under
server
in rollup.config.js or, more simply, install the
package to devDependencies
rather than dependencies
, which will cause it to
get bundled (and therefore compiled) with your app:
npm install --save-dev @sveltejs/svelte-virtual-list
If your project lives outside the WSL root directory, this limitation is known to cause live-reloading to fail. See this issue for details.
Please note that the default GDS Transport font is only licenced for subdomains
of service.gov.uk
. Please see the
GOV.UK Design System's note on fonts
if you're not sure what this means for your project.
Some of the templates and patterns in this repository are covered by the Open Government Licence 3.0, where they were sourced from the GOV.UK Design System.
The remaining code and content of this repository that originated in the template it was created from is covered by the Climate Strike (MIT) License 1.0. That means that it may not be used by companies that rely on fossil fuel extraction as their primary means of revenue.