Skip to content

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cannot have an _error.tsx file without a 404.tsx file #12256

Closed
eiskalteschatten opened this issue Apr 27, 2020 · 9 comments
Closed

Cannot have an _error.tsx file without a 404.tsx file #12256

eiskalteschatten opened this issue Apr 27, 2020 · 9 comments
Assignees
Labels
Documentation Related to Next.js' official documentation.
Milestone

Comments

@eiskalteschatten
Copy link

Bug report

Describe the bug

It isn't possible to have an _error.tsx file in the /pages folder without also having a 404.tsx file. When running next dev, it works fine, but as soon as you run next build, the following error appears:

Automatically optimizing pages ...
Error occurred prerendering page "/404". Read more: https://err.sh/next.js/prerender-error:
Error: Error for page /_error: pages with `getServerSideProps` can not be exported. See more info here: https://err.sh/next.js/gss-export

According to the official Next.js Blog, it should not be a problem to have a _error.tsx without a 404.tsx: https://nextjs.org/blog/next-9-3#automatic-static-optimization-for-404

The reason I do not want a static 404 page is so that I can catch routes with a trailing slash and redirect accordingly to the route without a trailing slash. This must be done on the server.

To Reproduce

Steps to reproduce the behavior, please provide code snippets or a repository:

  1. Create an _error.tsx file with a getServerSideProps() function.
  2. Run next build.

Expected behavior

The error message says that it is trying to export the _error.tsx file even though it obviously shouldn't be. The application should still build. As soon as I add a 404.tsx file or remove the _error.tsx file, it builds without a problem.

System information

  • OS: macOS and Alpine Linux (Docker)
  • Version of Next.js: 9.3
  • Version of Node.js: 13.13.0 and 14.0.0

Additional context

Just in case it might be of any use, here is the code from my _error.tsx file:

import React, { useEffect } from 'react';
import { GetServerSideProps } from 'next';
import Head from 'next/head';
import Router from 'next/router';

import { makeStyles, createStyles } from '@material-ui/core/styles';
import Container from '@material-ui/core/Container';

import useStandardHeaderTags from '../lib/useStandardHeaderTags';
import TitleElement from '../components/TitleElement';

const useStyles = makeStyles(() =>
  createStyles({
    root: {
      textAlign: 'center'
    }
  })
);

interface Props {
  statusCode: number;
}

const Error: React.FC<Props> = ({ statusCode }) => {
  const classes = useStyles();
  const title = statusCode === 404 ? '404' : 'Error';

  return (
    <>
      <Head>
        {useStandardHeaderTags(title)}
      </Head>
      <Container className={classes.root}>
        <TitleElement text={title} />

        {statusCode === 404
          ? 'The page you are looking for could not be found.'
          : 'An error occurred.'}
      </Container>
    </>
  );
};

export const getServerSideProps: GetServerSideProps = async ({ res, req }) => {
  const statusCode = res ? res.statusCode : 404;

  if (statusCode === 404) {
    if (req.url.match(/\/$/)) {
      const withoutTrailingSlash = req.url.substr(0, req.url.length - 1);
      if (res) {
        res.writeHead(303, {
          Location: withoutTrailingSlash
        });
        res.end();
      }
      else {
        Router.push(withoutTrailingSlash);
      }
    }
  }

  return {
    props: {
      statusCode
    }
  };
};

export default Error;
@timneutkens
Copy link
Member

Same as #12246

@timneutkens
Copy link
Member

Replied here: #11945 (reply in thread)

@timneutkens
Copy link
Member

timneutkens commented Apr 28, 2020

The reason I do not want a static 404 page is so that I can catch routes with a trailing slash and redirect accordingly to the route without a trailing slash. This must be done on the server.

What you're looking for seems to be #9081

pages/_error can't use getServerSideProps on purpose as explained in #11945 (reply in thread). pages/404.js can't use getServerSideProps on purpose too as it massively increases server load without a good reason, eg all 404 routes would server-render on-demand with the code that you wrote.

What we can do is improve the error message / documentation around it.

@eiskalteschatten
Copy link
Author

Thank you for the replies! What isn’t clear to me though is whether the redirects feature is already available in the latest version of Next.js as it was still marked as open. Also, is it possible to create a redirect with a regex-based src key so that I can redirect all routes with a trailing slash?

This issue is unfortunately holding up the launch our website...

@eiskalteschatten
Copy link
Author

I was, however, able to solve it by changing the getServierSideProps function to

Error.getInitialProps = ({ res, req, err }): Props => {
  const statusCode = res ? res.statusCode : err ? err.statusCode : 404;

  if (statusCode === 404) {
    if (req.url.match(/\/$/)) {
      const withoutTrailingSlash = req.url.substr(0, req.url.length - 1);
      if (res) {
        res.writeHead(303, {
          Location: withoutTrailingSlash
        });
        res.end();
      }
      else {
        Router.push(withoutTrailingSlash);
      }
    }
  }

  return { statusCode };
};

That works well.

@santialbo
Copy link

santialbo commented May 11, 2020

pages/_error can't use getServerSideProps on purpose as explained in #11945 (reply in thread). pages/404.js can't use getServerSideProps on purpose too as it massively increases server load without a good reason, eg all 404 routes would server-render on-demand with the code that you wrote.

Shouldn't be this up to the developer to decide? Feels like being too babysitted here. In our case we would like to serve different 404 pages depending on the language. Now I'm forced to use a useEffect inside the 404 page to trigger the language change, which shows a flash of the English version.

@Zauberfisch
Copy link

Zauberfisch commented Oct 26, 2020

Has this possibly been fixed?

I've just tested next with just index.js, _app.js and _error.js and it worked without a 404.js.

@Zauberfisch
Copy link

nvm, this bug is still present.
When _error.js has getInitialProps a 404.js is not required, but otherwise it is

@MerlinMason
Copy link

Yeah this seems confusing.

I followed the steps detailed in the Sentry docs, which makes no mention of also requiring a 404 file as well as a _error file.

However, this is contradicted in the Next example with Sentry.

Intuitively, it makes sense I can either have a specific 404 page, or a general error page.

As it stands, it's not clear why both are required, what the dependency is between them, or what the logic is to determine which one to show.

@balazsorban44 balazsorban44 added Documentation Related to Next.js' official documentation. and removed area: documentation labels Apr 17, 2024
@vercel vercel locked and limited conversation to collaborators Apr 17, 2024
@balazsorban44 balazsorban44 converted this issue into discussion #64631 Apr 17, 2024

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

Labels
Documentation Related to Next.js' official documentation.
Projects
None yet
Development

No branches or pull requests

9 participants