Gatsby Advanced Pages

Gatsby Advanced Pages is a wrapper around Gatsby's createPage API, making it easier to create pages with advanced features like pagination and custom routing.
Installation
Install using npm:
npm install gatsby-plugin-advanced-pages
Or with Yarn:
yarn add gatsby-plugin-advanced-pages
Demo
Check out the example directory for sample implementations.
A live demo is available at: mohatt.github.io/gatsby-plugin-advanced-pages.
Usage
To enable the plugin, add it to your gatsby-config.js
:
plugins: [
{
resolve: 'gatsby-plugin-advanced-pages',
options: {
},
},
]
TypeScript
The plugin is fully type-safe and provides comprehensive TypeScript typings for all its exports.
if you’re using Typescript, add it to your gatsby-config.ts
like this:
import type { PluginOptions as AdvancedPagesOptions } from 'gatsby-plugin-advanced-pages/node'
plugins: [
{
resolve: 'gatsby-plugin-advanced-pages',
options: {
} as AdvancedPagesOptions,
},
]
Creating pages
To create a new page, define your routes in pages.config.yaml
(or JSON/JS) at the root of your project:
- title: Hello, World
template: hello.js
routes:
hello: /hello
Next, create the corresponding template file under src/templates
:
import * as React from 'react'
import { graphql } from 'gatsby'
const HelloPage = ({ data }) => (
<div>
<h1>{data.page.title}</h1>
<p>Welcome to Gatsby Advanced Pages!</p>
</div>
)
export const query = graphql`
query HelloPageQuery($id: String!) {
page(id: { eq: $id }) {
title
}
}
`
export default WelcomePage
Run gatsby develop
, then visit http://localhost/hello
to see your new page.
Page helpers
For more advanced pages, define a page helper function that runs in Gatsby’s createPage lifecycle.
For example, to create a blog index page with pagination, first update pages.config.yaml
:
Note: You will need gatsby-transformer-remark plugin installed for this example to work
- title: Blog
routes:
blog: /blog
template: blog-template.js
helper: blog-helper.js
Next, create the page helper under gatsby/pages
module.exports = async function ({ graphql, page, createAdvancedPage }) {
const result = await graphql(`
{
allMarkdownRemark(filter: { frontmatter: { type: { eq: "post" } } }) {
totalCount
}
}
`)
if (result.errors) {
throw result.errors
}
createAdvancedPage({
route: 'blog',
pagination: {
count: result.data.allMarkdownRemark.totalCount,
limit: 3,
},
})
}
Finally, create the template file under src/templates
:
import * as React from 'react'
import { graphql } from 'gatsby'
import { Pagination } from 'gatsby-plugin-advanced-pages'
const BlogTemplate = ({ data }) => (
<div>
<h1>{data.page.title}</h1>
<div>
{data.allMarkdownRemark.edges.map(({ node }) => (
<div key={node.frontmatter.slug}>
<h2>{node.frontmatter.title}</h2>
<p>{node.excerpt}</p>
</div>
))}
</div>
<Pagination route='blog' pageInfo={data.allMarkdownRemark.pageInfo} ui='simple' />
</div>
)
export const query = graphql`
query BlogQuery($id: String!, $limit: Int!, $offset: Int!) {
page(id: { eq: $id }) {
title
}
allMarkdownRemark(
limit: $limit
skip: $offset
filter: { frontmatter: { type: { eq: "post" } } }
) {
edges {
node {
frontmatter {
title
slug
}
excerpt(pruneLength: 200)
}
}
pageInfo {
...Pagination
}
}
}
`
export default BlogTemplate
Now assuming you have 12 blog posts (stored as Markdown files), the plugin will create the following pages:
- /blog
- blog/page/2
- blog/page/3
- blog/page/4
if you want to customize the paginated paths, you can include a route
in your pagination object that's being passed to createAdvancedPage()
. See below:
- title: Blog
routes:
blog: /blog
blog.paginated: /blog/what/ever/:page
template: blog-template.js
helper: blog-helper.js
createAdvancedPage({
route: 'blog',
pagination: {
route: 'blog.paginated',
count: result.data.allMarkdownRemark.totalCount,
limit: 3,
},
})
Now the plugin will create the following pages:
- /blog
- /blog/what/ever/2
- /blog/what/ever/3
- /blog/what/ever/4
Passing data to templates
You can pass structured data from your pages.config.yaml
to your template component by setting the data
field. See below
- title: My skills
template: skills.js
routes:
skills: /skills
data:
skills:
- name: HTML
level: Excellent
- name: Javascript
level: Intermediate
Then, you can use that data in your template
import * as React from 'react'
import { graphql } from 'gatsby'
const SkillsTemplate = ({ data: { page } }) => (
<div>
<h1>{page.title}</h1>
<ul>
{page.data.sills.map(({ name, level }) => (
<li key={name}>
<strong>{name}:</strong> {level}
</li>
))}
</ul>
</div>
)
export const query = graphql`
query SkillsQuery($id: String!) {
page(id: { eq: $id }) {
title
data
}
}
`
export default SkillsTemplate
Generating paths
You can generate paths for the routes defined in your pages.config.yaml
using two methods:
Link component (recommended)
The Link component is a wrapper around Gatsby's Link component that allows passing route names and params in addition to regular paths.
Assuming you have a route named blog.post
with a value of /blog/posts/:post
, you can render a link to a specific blog post using the following:
import { Link } from 'gatsby-plugin-advanced-pages'
;<Link to='blog.post' params={{ post: 'some-post-slug' }} />
generatePath() function
Alternatively, you can use generatePath()
function to generate paths. see below:
import { generatePath } from 'gatsby-plugin-advanced-pages'
const postUrl = generatePath('blog.post', { post: 'some-post-slug' })
Components
The plugin exposes a set of components and functions that allow building advanced pages with minimal code.
Link component
Wrapper around Gatsby's core Link component that allows passing route names and params in addition to regular paths.
Props
to | String | Required. The name of the route to link to or a regular path |
params | Object | Route parameters |
scope | String | Route scope. Available scopes: pagination |
... | [...] | All props supported by Gatsby Link component |
Usage
import { Link } from 'gatsby-plugin-advanced-pages'
;<Link to='about' />
;<Link to='blog.post' params={{ post: 'some-post-slug' }} />
;<Link to='blog' scope='pagination' params={{ page: 4 }} />
;<Link to='about' activeClassName='active' partiallyActive={true} />
;<Link to='some/path' />
Renders a pagination UI to paginate a set of results fetched using a GraphQL query.
Props
route | String | Required. The name of the route to paginate |
params | Object | Route parameters |
pageInfo | Object | Required. pageInfo object fetched from GraphQL using Pagination fragment |
ui | String | UI mode (Defaults to full ). Available options: mini , simple , full |
range | Number | Maximum number of pages displayed (Defaults to 6) |
className | String | Class name applied to the pagination container |
labels | Object | Navigation items labels. Available keys: prev , next , first , last |
theme | Object | Elements class names (Defaults to Bootstrap 4 classes). Available keys: inner , item , item.next , item.prev , item.first , item.last , link , active , disabled |
renderDisabled | boolean | Render disabled navigation items (Defaults to true ) |
Usage
import { Pagination } from 'gatsby-plugin-advanced-pages'
const BlogTemplate = ({ data }) => {
;<Pagination ui='simple' route='blog' pageInfo={data.allMarkdownRemark.pageInfo} />
}
export const query = graphql`
query BlogQuery($limit: Int!, $offset: Int!) {
allMarkdownRemark(limit: $limit, skip: $offset){
edges {
node {
...
}
}
pageInfo {
...Pagination
}
}
}
`
export default BlogTemplate
Hooks
The plugin exposes two hooks for getting and checking for the currently activated route.
useRoute
(): Route
Gets the current active route based on @reach/router
location history.
useIsRoute
(route: string): boolean
Checks whether a given route is currently active.
Functions
These are the functions exposed by the plugin.
createAdvancedPage
({ route: string, params?: object, pagination?: object, ...context: any[] }): void
Creates page(s) based on given input parameters. Note: This function can only be called within Page helpers.
generatePath
(route: string, params?: object, scope?: string, ignorePrefix?: boolean): string
Generates a path for a specific route based on the given parameters.
getPathGenerator
(route: string, scope?: string, ignorePrefix?: boolean): Function
Returns a function to be used to generate paths for a specific route.
navigate
(to: string, params?: object, scope?: string, options?: object): void
Extends Gatsby's navigate to allow passing route names and params.
getMatchingRoute
(path: string, ignorePrefix?: boolean): Route
Gets the route that matches a given path.
getRoutes
(parent?: string): Route[]
Gets an array of all routes or routes nested under a given parent route.
getRoute
(route: string): Route
Gets the Route object of a given route name.
routeExists
(route: string): boolean
Checks if a route is defined with the given name.
Configuration
Pages
Pages configuration defines your site’s pages and routes. It should be defined in one of two ways:
Inline definition
You can define it alongside other plugin options in your gatsby.config.js
file like this:
plugins: [
{
resolve: 'gatsby-plugin-advanced-pages',
options: {
pages: [
{
title: 'Hello, World',
template: 'hello.js',
routes: {
hello: '/hello',
},
},
],
},
},
]
Separate config file
This file should be in the root of your Gatsby site and should be in one of these formats:
YAML
pages.config.yaml
or pages.config.yml
- title: Hello, World
template: hello.js
routes:
hello: /hello
JSON
pages.config.json
[
{
"title": "Hello, World",
"template": "hello.js",
"routes": {
"hello": "/hello"
}
}
]
JavaScript (ESM is supported)
pages.config.js
, pages.config.cjs
or pages.config.mjs
module.exports = [
{
title: 'Hello, World',
template: 'hello.js',
routes: {
hello: '/hello',
},
},
]
export default [
{
title: 'Hello, World',
template: 'hello.js',
routes: {
hello: '/hello',
},
},
]
Plugin options
Defaults
Here is the full list of options with their default values.
plugins: [
{
resolve: 'gatsby-plugin-advanced-pages',
options: {
basePath: '/',
pages: [],
template: null,
directories: {
templates: 'src/templates',
helpers: 'gatsby/pages',
},
pagination: {
limit: 10,
suffix: '/page/:page',
},
typeNames: {
page: 'Page',
},
},
},
]
basePath
Type: String
Default: "/"
Root url for all pages created through the plugin
pages
Type: Array
Default: []
Inline pages configuration to use instead of a separate pages.config.js file
template
Type: String
Default: null
Default template to be used for pages with no template
metadata defined. It could be a file name located under {directories.templates}
or a path relative to your project's root directory.
directories.templates
Type: String
Default: "src/templates"
Location of template components used to render pages. The path could either be relative to your project's root directory or an absolute path
directories.helpers
Type: String
Default: "gatsby/pages"
Location of page helpers. The path could either be relative to your project's root directory or an absolute path
Type: Number
Default: 10
Default page size to be used when no limit
parameter is passed to createAdvancedPage()
Type: String
Default: "/page/:page"
Suffix to be added to the original route to generate a paginated route. This is only used when no paginated route is passed to createAdvancedPage()
typeNames.page
Type: String
Default: "Page"
Name of the page object type
License
MIT