gatsby: [v2] Refreshing a page then hitting back (browser back button) leads to 404

Description

I have a local project that is using the v2 of Gatsby. Eevrything works great except for the fact that a page refresh and a back button on the browser always leads to a 404. On that 404 page Gatsby displays a list of routes and the actual route (the one that responded with 404) is in that list.

http://localhost:8000/categories/release/
-----
Gatsby.js development 404 page
There's not a page yet at /categories/release/

Create a React.js component in your site directory at src/pages/categories/release.js and this page will automatically refresh to show the new page component you created.

If you were trying to reach another page, perhaps you can find it below.

Pages (7)
/tags/cards/
/tags/example/
/tags/release/
/categories/release/
/404/
/
/404.html

Environment

gatsby info --clipboard

  System:
    OS: Linux 4.17 Fedora 28 (Workstation Edition) 28 (Workstation Edition)
    CPU: x64 Intel(R) Core(TM) i7-6700HQ CPU @ 2.60GHz
    Shell: 4.4.23 - /bin/bash
  Binaries:
    Node: 10.7.0 - /usr/bin/node
    Yarn: 1.9.4 - /usr/bin/yarn
    npm: 6.1.0 - /usr/bin/npm
  Browsers:
    Chrome: 68.0.3440.75
    Firefox: 61.0.1
  npmPackages:
    gatsby: next => 2.0.0-beta.97 
    gatsby-1-config-css-modules: next => 1.0.10-13 
    gatsby-image: next => 2.0.0-beta.7 
    gatsby-plugin-google-fonts: 0.0.4 => 0.0.4 
    gatsby-plugin-mailchimp: 2.2.3 => 2.2.3 
    gatsby-plugin-netlify: ^2.0.0-beta.6 => 2.0.0-beta.6 
    gatsby-plugin-react-helmet: next => 3.0.0-beta.4 
    gatsby-plugin-sass: next => 2.0.0-beta.10 
    gatsby-plugin-sharp: next => 2.0.0-beta.7 
    gatsby-plugin-styled-components: next => 3.0.0-beta.3 
    gatsby-plugin-typescript: next => 2.0.0-beta.9 
    gatsby-source-contentful: next => 2.0.1-beta.15 
    gatsby-source-filesystem: next => 2.0.1-beta.10 
    gatsby-transformer-sharp: next => 2.1.1-beta.6 
  npmGlobalPackages:
    gatsby-cli: 1.1.58
    gatsby: 2.0.0-beta.54

File contents (if changed)

gatsby-config.js:

let contentfulConfig, mailchimpConfig;

try {
	contentfulConfig = require('./config/contentful.json');
} catch (_) {
	contentfulConfig = {
		spaceId: process.env.CONTENTFUL_SPACE_ID,
		accessToken: process.env.CONTENTFUL_DELIVERY_TOKEN,
	}
}

try {
	mailchimpConfig = require('./config/mailchimp.json')
} catch (_) {
	mailchimpConfig = {
		endpoint: process.env.MAILCHIMP_ENDPOINT
	}
}

module.exports = {
	plugins: [
		'gatsby-plugin-react-helmet',
		`gatsby-plugin-typescript`,
		`gatsby-transformer-sharp`,
		`gatsby-plugin-sharp`,
		`gatsby-plugin-sass`,
		`gatsby-plugin-styled-components`,
		{
			resolve: `gatsby-plugin-google-fonts`,
			options: {
				fonts: [
					`Roboto:300,300i,400,400i,500,500i,600,600i`,
				],
			},
		},
		{
			resolve: `gatsby-source-contentful`,
			options: contentfulConfig,
		},
		{
			resolve: 'gatsby-plugin-mailchimp',
			options: mailchimpConfig,
		},
		`gatsby-plugin-netlify`, // make sure to keep it last in the array
	],
};

package.json:

{
  "name": "",
  "description": "",
  "version": "1.0.0",
  "author": "",
  "dependencies": {
    "@blueprintjs/core": "^3.0.1",
    "autoprefixer": "^9.0.1",
    "babel-plugin-styled-components": "^1.5.1",
    "extract-text-webpack-plugin": "^3.0.2",
    "gatsby": "next",
    "gatsby-1-config-css-modules": "next",
    "gatsby-image": "next",
    "gatsby-plugin-google-fonts": "0.0.4",
    "gatsby-plugin-mailchimp": "2.2.3",
    "gatsby-plugin-netlify": "^2.0.0-beta.6",
    "gatsby-plugin-react-helmet": "next",
    "gatsby-plugin-sass": "next",
    "gatsby-plugin-sharp": "next",
    "gatsby-plugin-styled-components": "next",
    "gatsby-plugin-typescript": "next",
    "gatsby-source-contentful": "next",
    "gatsby-source-filesystem": "next",
    "gatsby-transformer-sharp": "next",
    "grid-styled": "^5.0.2",
    "install": "^0.12.1",
    "lodash": "^4.17.10",
    "lodash.debounce": "^4.0.8",
    "moment": "^2.22.2",
    "node-sass": "^4.9.2",
    "npm": "^6.3.0",
    "prismjs": "^1.15.0",
    "react": "^16.4.1",
    "react-accessible-accordion": "^2.4.4",
    "react-custom-scrollbars": "^4.2.1",
    "react-dom": "^16.4.1",
    "react-helmet": "^5.2.0",
    "react-player": "^1.6.4",
    "react-prism": "^4.3.2",
    "react-redux": "^5.0.7",
    "react-share": "^2.2.0",
    "react-slick": "^0.23.1",
    "remark": "^9.0.0",
    "remark-react": "^4.0.3",
    "slick-carousel": "^1.8.1",
    "styled-components": "^3.3.3",
    "tinycolor2": "^1.4.1"
  },
  "keywords": [
    "static site",
    "cards",
    "smart cards",
    "blog"
  ],
  "license": "MIT",
  "scripts": {
    "build": "gatsby build",
    "develop": "gatsby develop",
    "format": "prettier --write '**/*.js'",
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "devDependencies": {
    "@types/grid-styled": "^4.2.0",
    "@types/lodash": "^4.14.115",
    "@types/moment": "^2.13.0",
    "@types/node": "^10.5.5",
    "@types/prismjs": "^1.9.0",
    "@types/prop-types": "^15.5.4",
    "@types/reach__router": "^1.0.0",
    "@types/react": "^16.4.7",
    "@types/react-dom": "^16.0.6",
    "@types/react-helmet": "^5.0.6",
    "@types/react-redux": "^6.0.5",
    "@types/react-share": "^2.1.1",
    "@types/react-transition-group": "^2.0.13",
    "@types/tinycolor2": "^1.4.1",
    "prettier": "^1.13.7",
    "redux-devtools-extension": "^2.13.5"
  },
  "repository": {
    "type": "git",
    "url": ""
  }
}

gatsby-node.js:

const _ = require('lodash');
const Promise = require('bluebird');
const path = require('path');
const {createFilePath} = require(`gatsby-source-filesystem`);
const {createRemoteFileNode} = require(`gatsby-source-filesystem`);

const getTags = (edges) => {
	const tags = [];

	_.each(edges, edge => {
		if (_.get(edge, "node.tags")) {
			for (let i = 0; i < edge.node.tags.length; i++) {
				tags.push(edge.node.tags[i]);
			}
		}
	});

	return tags;
};

const getCategories = (edges) => {
	const categories = [];

	_.each(edges, edge => {
		if (_.get(edge, "node.categories")) {
			for (let i = 0; i < edge.node.categories.length; i++) {
				categories.push(edge.node.categories[i]);
			}
		}
	});

	return categories;
};

exports.createPages = ({graphql, actions}) => {
	const {createPage} = actions;

	return new Promise((resolve, reject) => {
		const postTemplate = path.resolve('./src/templates/post/index.tsx');
		const tagTemplate = path.resolve("./src/templates/tag/index.tsx");
		const categoryTemplate = path.resolve("./src/templates/category/index.tsx");

		resolve(graphql(`
				{
					allContentfulPost(sort: {fields: [createdAt], order: DESC}) {
						edges {
							node {
								id
								slug
								
								tags {
									id
									slug
									title
								}

								categories {
									id
									slug
									title
								}

								createdAt
								updatedAt
							}
						}
					}
				}
			`).then(result => {
			if (result.errors) {
				console.error(result.errors);
				reject(result.errors);
			}

			const edges = result.data.allContentfulPost.edges;

			const tags = getTags(edges);
			const categories = getCategories(edges);

			// Create posts and pages.
			_.each(edges, (edge, index) => {
				const slug = edge.node.slug;

				const previous = index === edges.length - 1 ? null : edges[index + 1].node;
				const next = index === 0 ? null : edges[index - 1].node;

				//	create posts pages
				createPage({
					path: `/posts/${slug}/`,
					component: postTemplate,
					context: {
						slug: slug,
						previous,
						next,
					},
				});
			});

			// Make tag pages
			_.uniq(tags).forEach(tag => {
				createPage({
					path: `/tags/${tag.slug}/`,
					component: tagTemplate,
					context: {
						slug: tag.slug
					},
				})
			});

			// Make category pages
			_.uniqBy(categories, 'id').forEach(category => {
				createPage({
					path: `/categories/${category.slug}/`,
					component: categoryTemplate,
					context: {
						slug: category.slug
					},
				})
			});
		}));
	});
};

gatsby-browser.js: N/A gatsby-ssr.js: N/A

NO console errors shown.

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Comments: 19 (10 by maintainers)

Commits related to this issue

Most upvoted comments

Putting this here for ref Bug is visible using the Gatsby default starter v2. On gatsby develop, nothing displays when the back button is clicked. On gatsby build the current page is retained even with the new URL.

Repro: https://github.com/Chuloo/gatsby-7261

Ok, got this working in a rather brutal way. For those who want a quick (no forking required), but very dirty fix:

Click to see dirty fix 🙈
// gatsby-browser.js

exports.onInitialClientRender = () => {
  // dirty fix for missing popstate listener
  const GATSBY_NAVIGATE = window.___navigate || {}

  window.addEventListener('popstate', () =>
    GATSBY_NAVIGATE(window.location.pathname, { replace: true })
  )
}

Explanation: there is no listener for the popstate event thus the Gatsby site has no clue the route has changed. We can patch this using the exposed __navigate method with replace: true param. It will manage all the prefetching & rendering work. Thanks to { replace: true } flag, the navigation event coming from the reach router will be “meged & squashed” with the popstate one.

@Chuloo If you could please help me out on where to put this listener within the codebase, I’d be more than happy to come up with a PR. I guess somewhere here might be a good place?

Cheers

Just reopening this because I haven’t verified if it’s fixed yet - GitHub thought it was fixed because I wrote “fixes” before the number

image

Edit: yep, I’m still able to reproduce this after #7788.

Not sure what’s wrong just on the off-hand, but I can check this out later. It could be something I broke in #7355 to be honest…