Next.js возвращает страницу с ошибкой 404 в getInitialProps

В настоящее время я следую этому примеру о том, как перенаправлять пользователей в getInitialProps.

https://github.com/zeit/next.js/wiki/Redirecting-in-%60getInitialProps%60

Проблема в том, что если я хочу вернуть 404 таким образом, он вернет пустую страницу вместо обычной страницы ошибки 404 Next.js.

context.res.writeHead(404)
context.res.end();

Обратите внимание, что я знаю, что использование ExpressJs и код состояния 404 работают, однако для этого проекта мне не разрешено использовать ExpressJ, поэтому для этого мне нужно использовать типичные nodejs writeHead.


person Thomas Charlesworth    schedule 01.12.2017    source источник
comment
Next.js 10 делает это очень простым, последний ответ можно найти ниже.   -  person Master Noob    schedule 15.01.2021


Ответы (6)


Для этого вам необходимо отобразить страницу с ошибкой на своей странице.

Вы можете сделать что-то вроде этого:

import React from 'react'
import ErrorPage from 'next/error'

class HomePage extends React.Component {
  static async getInitialProps(context) {
    try {
      const data = await retrieveSomeData()
      return { data }
    } catch (err) {
      // Assuming that `err` has a `status` property with the HTTP status code.
      if (context.res) {
        context.res.writeHead(err.status)
      }
      return { err: { statusCode: err.status } }
    }
  }

  render() {
    const { err, data } = this.props

    if (err) {
      return <ErrorPage statusCode={err.statusCode} />
    }

    /*
     * return <Something data={data} />
     */
  }
}

Если у вас есть настраиваемая страница ошибок, вместо импорта next/error вам придется импортировать настраиваемую _error страницу.

person Bertrand Marron    schedule 14.12.2017

Следующая v10 позволяет вернуть страницу 404 (не с реквизитом, а просто, как показано ниже)

  if (!checkItem) {
    return {
      notFound: true
    }
  }

Полный код, который у меня работает: ✅✅✅

export const getServerSideProps = wrapper.getServerSideProps(async ({ req, res, locale, query, store }) => {
  const { productId, categoryId } = query
   
  const checkItem = await getProductBySlugSSR(productId, categoryId, store)

  if (!checkItem) {
    return { // <-----------------does the trick here!!
      notFound: true
    }
  }
    
  return {
    props: {
      ...await serverSideTranslations(locale, ['common']),
    }
  }
})

Документация: https://nextjs.org/blog/next-10#notfound-support < / а>

person Alex Karpov    schedule 28.04.2021
comment
Это должен быть принятый ответ на 2021 год. (Next.js v10.2) - person Vadorequest; 26.05.2021
comment
@Vadorequest нет, OP запрашивал getInitialProps, но поддержка не найдена, доступна только для getStaticProps и getServerSideProps - person RaenonX; 07.06.2021
comment
Откуда wrapper? - person Newbyte; 09.06.2021
comment
@Newbyte это происходит из: import {HYDRATE, createWrapper} from 'next-redux-wrapper' export const wrapper = createWrapper (initStore) - person Alex Karpov; 09.06.2021

Начиная с NextJS 10, теперь вы можете включить notFound: true в объект возврата getStaticProps && getServerSideProps для перенаправления на страницу 404

Вот примечания к выпуску: https://nextjs.org/blog/next-10#redirect-and-notfound-support-for-getstaticprops--getserversideprops

person Master Noob    schedule 14.01.2021

Реализуйте свой getInitialProps следующим образом:

    static async getInitialProps(context) {
        const {res} = context;

        ...

        if ([something went wrong]) {
            if (res) {
                res.statusCode = 404;
            }

            return {
                err: {
                    statusCode: 404
                },
            };
        }
        ...

Затем в render () проверьте, определен ли err в состоянии, и в этом случае верните ErrorPage (по умолчанию или настраиваемый, в зависимости от вашей реализации) и все! StatusCode внутри err предназначен только для более детального сообщения на ErrorPage, поэтому его необходимо передать для него в качестве реквизита.

person Strobotti    schedule 16.01.2019

import App, { Container } from 'next/app'
import React from 'react'
import Head from 'next/head'
import * as Sentry from '@sentry/node'
import Error from './_error'

require('es6-promise').polyfill()
require('isomorphic-fetch')

class MyApp extends App {
  static async getInitialProps({ Component, ctx }) {
    let pageProps = {}
    let e
    if (Component.getInitialProps) {
      try {
        pageProps = await Component.getInitialProps(ctx)
      } catch (error) {
        e = error
        Sentry.captureException(error) //report to sentry
      }
    }
    return { pageProps, e }
  }

  render() {
    const { Component, pageProps, e } = this.props
    if (e) {
      return <Error /> // customize your error page
    }
    return (
      <Container>
        <Head>
          <title> Your title</title>
        </Head>
        <Component {...pageProps} />
      </Container>
    )
  }
}

export default MyApp

Это работает как шарм ~ просто попробуйте catch в следующем / app, тогда он работает для всех страниц

person Shawn Wang    schedule 25.01.2019

Если вам просто нужно реализовать 404 СТРАНИЦУ, как в cra

предоставленный код может быть полезным: например.

 import AComponent from '../acomponent';
 import Error from '../error';
  
 const User = (data) => {

   return data.id ? <AComponent /> : <Error />
 }

 User.getInitialProps = async (ctx) => {
   const res = await fetch(...data) // list of items = []
   const data = await res.json()

   return data;
 }
person Vince    schedule 01.10.2020