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.
Install using npm:
npm install gatsby-plugin-advanced-pages
Or with Yarn:
yarn add gatsby-plugin-advanced-pages
Check out the example directory for sample implementations.
A live demo is available at: mohatt.github.io/gatsby-plugin-advanced-pages.
To enable the plugin, add it to your gatsby-config.js
:
plugins: [
{
resolve: 'gatsby-plugin-advanced-pages',
options: {
// Plugin options goes here
},
},
]
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: {
// Plugin options goes here
} as AdvancedPagesOptions,
},
]
To create a new page, define your routes in pages.config.yaml
(or JSON/JS) at the root of your project:
# pages.config.yaml
- title: Hello, World
template: hello.js
routes:
hello: /hello
Next, create the corresponding template file under src/templates
:
// src/templates/hello.js
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.
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
# pages.config.yaml
- title: Blog
routes:
blog: /blog
template: blog-template.js
helper: blog-helper.js
Next, create the page helper under gatsby/pages
// gatsby/pages/blog-helper.js
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
:
// src/templates/blog-template.js
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:
# pages.config.yaml
- title: Blog
routes:
blog: /blog
blog.paginated: /blog/what/ever/:page
template: blog-template.js
helper: blog-helper.js
// gatsby/pages/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
You can pass structured data from your pages.config.yaml
to your template component by setting the data
field. See below
# content/pages/skills.md
- 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
// src/templates/skills.js
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
You can generate paths for the routes defined in your pages.config.yaml
using two methods:
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'
// inside your component JSX
;<Link to='blog.post' params={{ post: 'some-post-slug' }} />
Alternatively, you can use generatePath()
function to generate paths. see below:
import { generatePath } from 'gatsby-plugin-advanced-pages'
// Returns: /blog/posts/some-post-slug
const postUrl = generatePath('blog.post', { post: 'some-post-slug' })
The plugin exposes a set of components and functions that allow building advanced pages with minimal code.
Wrapper around Gatsby's core Link component that allows passing route names and params in addition to regular paths.
Name | Type | Description |
---|---|---|
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 |
import { Link } from 'gatsby-plugin-advanced-pages'
// Route: about = /about-me
// Output: <GatsbyLink to="/about-me" />
;<Link to='about' />
// Route: blog.post = /blog/:post
// Output: <GatsbyLink to="/blog/some-post-slug" />
;<Link to='blog.post' params={{ post: 'some-post-slug' }} />
// Route: blog = /blog
// Output: <GatsbyLink to="/blog/page/4" />
;<Link to='blog' scope='pagination' params={{ page: 4 }} />
// You can pass any prop supported by GatsbyLink
// Output: <GatsbyLink to="/about-me" activeClassName="active" partiallyActive={true} />
;<Link to='about' activeClassName='active' partiallyActive={true} />
// If no valid route is supplied, a regular link will be rendered
// Output: <GatsbyLink to="/some/path" />
;<Link to='some/path' />
Renders a pagination UI to paginate a set of results fetched using a GraphQL query.
Name | Type | Description |
---|---|---|
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 ) |
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
The plugin exposes two hooks for getting and checking for the currently activated route.
(): Route
Gets the current active route based on @reach/router
location history.
(route: string): boolean
Checks whether a given route is currently active.
These are the functions exposed by the plugin.
({ 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.
(route: string, params?: object, scope?: string, ignorePrefix?: boolean): string
Generates a path for a specific route based on the given parameters.
(route: string, scope?: string, ignorePrefix?: boolean): Function
Returns a function to be used to generate paths for a specific route.
(to: string, params?: object, scope?: string, options?: object): void
Extends Gatsby's navigate to allow passing route names and params.
(path: string, ignorePrefix?: boolean): Route
Gets the route that matches a given path.
(parent?: string): Route[]
Gets an array of all routes or routes nested under a given parent route.
(route: string): Route
Gets the Route object of a given route name.
(route: string): boolean
Checks if a route is defined with the given name.
Pages configuration defines your site’s pages and routes. It should be defined in one of two ways:
You can define it alongside other plugin options in your gatsby.config.js
file like this:
plugins: [
{
resolve: 'gatsby-plugin-advanced-pages',
options: {
// plugin options goes here
pages: [
{
title: 'Hello, World',
template: 'hello.js',
routes: {
hello: '/hello',
},
},
],
},
},
]
This file should be in the root of your Gatsby site and should be in one of these formats:
pages.config.yaml
or pages.config.yml
- title: Hello, World
template: hello.js
routes:
hello: /hello
pages.config.json
[
{
"title": "Hello, World",
"template": "hello.js",
"routes": {
"hello": "/hello"
}
}
]
pages.config.js
, pages.config.cjs
or pages.config.mjs
// CJS Syntax
module.exports = [
{
title: 'Hello, World',
template: 'hello.js',
routes: {
hello: '/hello',
},
},
]
// ESM Syntax
export default [
{
title: 'Hello, World',
template: 'hello.js',
routes: {
hello: '/hello',
},
},
]
Here is the full list of options with their default values.
// gatsby-config.js
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',
},
},
},
]
Type:
String
Default:"/"
Root url for all pages created through the plugin
Type:
Array
Default:[]
Inline pages configuration to use instead of a separate pages.config.js file
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.
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
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()
Type:
String
Default:"Page"
Name of the page object type