npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@benwatsonuk/govuk-pages-plugin

v1.4.0

Published

A plugin to visualise selected pages of a GOV.UK prototype with a linear user journey or page index.

Readme

govuk-pages-plugin

A plugin for GOVUK Prototype Kit that shows selected pages in various indexes (lists) and visualises user flows and journeys so that users can navigate directly to them.

The idea is that by providing elevated perspectives of journeys and pages, designers and UCD teams can discuss them without the high fidelity detail of the page, affording them the option of choosing when it is appropriate to 'zoom in' to this detail.

The plugin also gives the option of an 'overview' page which allows UCD teams to give some additional context to pages with a 'semi zoomed-in' view, this can be useful to showcase variants, iterations or states of a given page.

Requirements

To use this plugin, first start a prototype by installing the GOV.UK Prototype Kit (version 13 or later).

1. Install the plugin

In the folder that contains your prototype, install the plugin by running the following terminal command:

npm install https://github.com/benwatsonuk/govuk-pages-plugin

2. Add the following code to your prototype's routes.js file(s)

Basic Setup

const { govukPagesPlugin, pageOverview } = require('@benwatsonuk/govuk-pages-plugin')

If you use multiple routes files, include the above code on the pages that you wish to use the features of the plugin on.

Then for the most basic implementation declare the route that you wish to use and call the function to generate all available flows and indexes from the data that you provide:

router.use(`/path-of-your-choice/pages`, govukPagesPlugin(pages, stages, flows))

router.get(`/path-of-your-choice/page/:pageId`, (req, res) => {
  pageOverview(Number(req.params.pageId), pages, req, res)
})

For all functions, you MUST provide a valid pages property (see below), stages and flows are always optional but provide some useful functionality. See below about how to use these optionally.

Advanced Setup

Call and use any of the exported functions available in dist/index.js file - this can be useful if you wish to use the plugin's data to create your own views or you wish to set up custom paths/routes.

See the examples below for more details.

Using the plugin

There are two main ways in which you might want to use the plugin.

  1. To supply the relevant page data (in the expected format - see below) and have the plugin render indexes, directories and user-flows using the supplied templates
  2. Create views yourself by supplying the relevant page data to the plugin and have it return a usable data object, that you can either use yourself or call components and templates from the plugin to create your own bespoke views

What data do I need to supply the plugin?

That depends on which of the plugin's features you wish to use. There are 3 types of data that you could provide the plugin:

  1. Page Data - REQUIRED - this is information at the page level, all pages that will be referenced or indexed will need to be included.
  2. Stage Data - OPTIONAL -this is a type of grouping that pages can belong to (they don't have to!) e.g. 'authentication' or 'registering' etc. it can group pages based on a subset of a journey.
  3. Flow Data - OPTIONAL - this type of data describes discrete journeys or flows. It can string pages together to visualise the journey a user might take.

Page Data (required)

At the most basic level, the plugin will need a list of pages to work with. This must be passed to the plugin (via the Express route) as a valid JSON object that matches the schema defined at https://github.com/benwatsonuk/govuk-pages-plugin/blob/main/src/schema.json under the 'pages' definition.

If you are familiar with TypeScript, you could also reference https://github.com/benwatsonuk/govuk-pages-plugin/blob/main/src/types.ts (see 'Page').

In future, hopefully this can be automated but for now, you will need to create this array in order to use the plugin.

Stage Data (optional)

Stages aren't required but they can add useful groupings to series of pages that are useful when visualising or listing a large number of pages at once. For example, a series of 'stages' that might exist when accessing your 'Personal Tax Account' from HMRC might be:

  • GOV.UK Guidance
  • Authentication
  • Personal Account Dashboard

There is also the concept of 'sub-stages' which allows you to break these down even further, for example:

  • Authentication
    • Select Method
    • Government Gateway
    • One Login
  • Personal Tax Account
    • PAYE
    • Account Management
    • Messages

If stages are provided and the page data refers to the relevant ID in the pages object, the ability to visualise by stages, group indexes by stages etc. will be possible.

Make sure the 'stages' array matches the schema defined at https://github.com/benwatsonuk/govuk-pages-plugin/blob/main/src/schema.json under the 'stages' definition.

If you are familiar with TypeScript, you could also reference https://github.com/benwatsonuk/govuk-pages-plugin/blob/main/src/types.ts (see 'Stage').

Flow Data (optional)

If this is passed to the plugin, we can visualise user journeys from end to end and the prototype will allow navigaton directly to the relevant pages. This can be useful when giving an overview of a flow that a user might go through, or to give context as to a page's position in a longer journey.

Examples

Most basic example:

const { govukPagesPlugin } = require('@benwatsonuk/govuk-pages-plugin')

// If you have all objects
router.use(`/path-of-your-choice/pages`, govukPagesPlugin(pages, stages, flows))

// If you have ONLY pages
router.use(`/path-of-your-choice/pages`, govukPagesPlugin(pages))

// If you have PAGES and STAGES objects
router.use(`/path-of-your-choice/pages`, govukPagesPlugin(pages, stages))

// If you have PAGES and FLOWS objects
router.use(`/path-of-your-choice/pages`, govukPagesPlugin(pages, null, flows))

Here are some recipes for adding data to your routes:

const { govukPagesPlugin, pageIndex, stageIndex, stageIndexData, pageIndexData } = require('@benwatsonuk/govuk-pages-plugin')

router.use(`/path-of-your-choice/pages`, govukPagesPlugin(pages, stages, flows))
router.use(`/path-of-your-choice/page-index`, pageIndex(pages))
router.use(`/path-of-your-choice/stage-index`, stageIndex(stages, pages))
router.use(`/path-of-your-choice/flow-index`, flowIndex(flows, pages, stages))

router.get(`/path-of-your-choice/stage-index-test`, (req, res) => {
  res.render(`path-of-your-choice/stage-index-test`, {
    stages: stageIndexData(stages, pages)
  })
})

router.get(`/path-of-your-choice/page-index-test`, (req, res) => {
  res.render(`path-of-your-choice/page-index-test`, {
    pages: pageIndexData(pages)
  })
})

router.get(`/path-of-your-choice/flow-index-test`, (req, res) => {
  res.render(`path-of-your-choice/flow-index-test`, {
    pages: flowIndexData(flows, pages, stages)
  })
})

Here are some examples of 'stage' and 'page' data arrays:

Pages

const pages = [
  {
    id: 1,
    title: 'Title 1',
    type: 'email',
    description: 'A description about item 1',
    route: '/a/a/1',
    stage: {main: 'stage1', subStage: 1}
  },
  {
    id: 2,
    title: 'Title 2',
    type: 'email',
    description: 'A description about item 2',
    route: '/b/b/2',
    stage: {main: 'stage2', subStage: 2}
  },
  {
    id: 3,
    title: 'Title 3',
    type: 'email',
    description: 'A description about item 3',
    route: '/a/b/3'
  }
];

Stages

const stages = [
  {
    id: 'stage1',
    title: 'Stage 1',
    description: 'A description about stage 1',
    route: '/a',
    subStages: [
      {
        id: 1,
        title: 'Sub-stage 1-1',
        description: 'A description about sub-stage 1-1',
        route: '/a/a'
      },
    {
        id: 2,
        title: 'Sub-stage 1-2',
        description: 'A description about sub-stage 1-2',
        route: '/a/b'
      }
    ]
  },
    {
    id: 'stage2',
    title: 'Stage 2',
    description: 'A description about stage 2',
    route: '/b',
    subStages: [
      {
        id: 1,
        title: 'Sub-stage 2-1',
        description: 'A description about sub-stage 2-1',
        route: '/b/a'
      },
    {
        id: 2,
        title: 'Sub-stage 2-2',
        description: 'A description about sub-stage 2-2',
        route: '/b/b'
      }
    ]
  }
]

Flows

const flows = [
  {
    id: 1,
    title: 'Flow 1',
    description: 'A description of Flow 1',
    user: 'User A',
    steps: [
      {
        pageId: 1
      },
      {
        pageId: 2
      }
    ]
  },
  {
    id: 2,
    title: 'Flow 2',
    description: 'A description of Flow 2',
    user: 'User B',
    steps: [
      {
        pageId: 2
      },
      {
        pageId: 3
      }
    ]
  }
];