next-with-error
Version:
Next.js HoC to render the Error page and send the correct HTTP status code from any page
143 lines (142 loc) • 8.7 kB
TypeScript
import React from 'react';
import { default as NextApp, AppInitialProps } from 'next/app';
import { NextComponentType, NextPageContext } from 'next';
export interface PageErrorInitialProps<T = Record<string, any>> {
error?: {
statusCode: number;
} & T;
}
export declare type ExcludeErrorProps<P> = Pick<P, Exclude<keyof P, keyof PageErrorInitialProps>>;
/**
* Small helper to generate errors object if needed
*/
export declare const generatePageError: <T extends Record<string, any>>(statusCode: number, params?: T | undefined) => PageErrorInitialProps<{} | T>;
/**
* This higher-order component is used to render the Error page if a HTTP status
* code >400 is thrown by one of the pages.
*
* To trigger it, just add statusCode to the object returned by getInitialProps
*
* This solution is based on Tim Neutkens's insights and inspired by Nuxt.js
* https://spectrum.chat/next-js/general/error-handling-in-async-getinitialprops~99400c6c-0da8-4de5-aecd-2ecf122e8ad0
* https://github.com/nuxt/nuxt.js/issues/895#issuecomment-308682972
*/
declare const withErrorHoC: (CustomErrorComponent?: (React.ComponentClass<any, any> & {
getInitialProps?(context: NextPageContext): any;
}) | (React.FunctionComponent<any> & {
getInitialProps?(context: NextPageContext): any;
}) | undefined) => <P extends PageErrorInitialProps<Record<string, any>>>(AppComponent: typeof NextApp) => {
new (props: Readonly<P & PageErrorInitialProps<Record<string, any>> & AppInitialProps & {
Component: NextComponentType<NextPageContext, any, {}>;
router: import("next/dist/client/router").Router;
}>): {
render(): JSX.Element;
context: any;
setState<K extends never>(state: {} | ((prevState: Readonly<{}>, props: Readonly<P & PageErrorInitialProps<Record<string, any>> & AppInitialProps & {
Component: NextComponentType<NextPageContext, any, {}>;
router: import("next/dist/client/router").Router;
}>) => {} | Pick<{}, K> | null) | Pick<{}, K> | null, callback?: (() => void) | undefined): void;
forceUpdate(callback?: (() => void) | undefined): void;
readonly props: Readonly<P & PageErrorInitialProps<Record<string, any>> & AppInitialProps & {
Component: NextComponentType<NextPageContext, any, {}>;
router: import("next/dist/client/router").Router;
}> & Readonly<{
children?: React.ReactNode;
}>;
state: Readonly<{}>;
refs: {
[key: string]: React.ReactInstance;
};
componentDidMount?(): void;
shouldComponentUpdate?(nextProps: Readonly<P & PageErrorInitialProps<Record<string, any>> & AppInitialProps & {
Component: NextComponentType<NextPageContext, any, {}>;
router: import("next/dist/client/router").Router;
}>, nextState: Readonly<{}>, nextContext: any): boolean;
componentWillUnmount?(): void;
componentDidCatch?(error: Error, errorInfo: React.ErrorInfo): void;
getSnapshotBeforeUpdate?(prevProps: Readonly<P & PageErrorInitialProps<Record<string, any>> & AppInitialProps & {
Component: NextComponentType<NextPageContext, any, {}>;
router: import("next/dist/client/router").Router;
}>, prevState: Readonly<{}>): any;
componentDidUpdate?(prevProps: Readonly<P & PageErrorInitialProps<Record<string, any>> & AppInitialProps & {
Component: NextComponentType<NextPageContext, any, {}>;
router: import("next/dist/client/router").Router;
}>, prevState: Readonly<{}>, snapshot?: any): void;
componentWillMount?(): void;
UNSAFE_componentWillMount?(): void;
componentWillReceiveProps?(nextProps: Readonly<P & PageErrorInitialProps<Record<string, any>> & AppInitialProps & {
Component: NextComponentType<NextPageContext, any, {}>;
router: import("next/dist/client/router").Router;
}>, nextContext: any): void;
UNSAFE_componentWillReceiveProps?(nextProps: Readonly<P & PageErrorInitialProps<Record<string, any>> & AppInitialProps & {
Component: NextComponentType<NextPageContext, any, {}>;
router: import("next/dist/client/router").Router;
}>, nextContext: any): void;
componentWillUpdate?(nextProps: Readonly<P & PageErrorInitialProps<Record<string, any>> & AppInitialProps & {
Component: NextComponentType<NextPageContext, any, {}>;
router: import("next/dist/client/router").Router;
}>, nextState: Readonly<{}>, nextContext: any): void;
UNSAFE_componentWillUpdate?(nextProps: Readonly<P & PageErrorInitialProps<Record<string, any>> & AppInitialProps & {
Component: NextComponentType<NextPageContext, any, {}>;
router: import("next/dist/client/router").Router;
}>, nextState: Readonly<{}>, nextContext: any): void;
};
new (props: P & PageErrorInitialProps<Record<string, any>> & AppInitialProps & {
Component: NextComponentType<NextPageContext, any, {}>;
router: import("next/dist/client/router").Router;
}, context?: any): {
render(): JSX.Element;
context: any;
setState<K extends never>(state: {} | ((prevState: Readonly<{}>, props: Readonly<P & PageErrorInitialProps<Record<string, any>> & AppInitialProps & {
Component: NextComponentType<NextPageContext, any, {}>;
router: import("next/dist/client/router").Router;
}>) => {} | Pick<{}, K> | null) | Pick<{}, K> | null, callback?: (() => void) | undefined): void;
forceUpdate(callback?: (() => void) | undefined): void;
readonly props: Readonly<P & PageErrorInitialProps<Record<string, any>> & AppInitialProps & {
Component: NextComponentType<NextPageContext, any, {}>;
router: import("next/dist/client/router").Router;
}> & Readonly<{
children?: React.ReactNode;
}>;
state: Readonly<{}>;
refs: {
[key: string]: React.ReactInstance;
};
componentDidMount?(): void;
shouldComponentUpdate?(nextProps: Readonly<P & PageErrorInitialProps<Record<string, any>> & AppInitialProps & {
Component: NextComponentType<NextPageContext, any, {}>;
router: import("next/dist/client/router").Router;
}>, nextState: Readonly<{}>, nextContext: any): boolean;
componentWillUnmount?(): void;
componentDidCatch?(error: Error, errorInfo: React.ErrorInfo): void;
getSnapshotBeforeUpdate?(prevProps: Readonly<P & PageErrorInitialProps<Record<string, any>> & AppInitialProps & {
Component: NextComponentType<NextPageContext, any, {}>;
router: import("next/dist/client/router").Router;
}>, prevState: Readonly<{}>): any;
componentDidUpdate?(prevProps: Readonly<P & PageErrorInitialProps<Record<string, any>> & AppInitialProps & {
Component: NextComponentType<NextPageContext, any, {}>;
router: import("next/dist/client/router").Router;
}>, prevState: Readonly<{}>, snapshot?: any): void;
componentWillMount?(): void;
UNSAFE_componentWillMount?(): void;
componentWillReceiveProps?(nextProps: Readonly<P & PageErrorInitialProps<Record<string, any>> & AppInitialProps & {
Component: NextComponentType<NextPageContext, any, {}>;
router: import("next/dist/client/router").Router;
}>, nextContext: any): void;
UNSAFE_componentWillReceiveProps?(nextProps: Readonly<P & PageErrorInitialProps<Record<string, any>> & AppInitialProps & {
Component: NextComponentType<NextPageContext, any, {}>;
router: import("next/dist/client/router").Router;
}>, nextContext: any): void;
componentWillUpdate?(nextProps: Readonly<P & PageErrorInitialProps<Record<string, any>> & AppInitialProps & {
Component: NextComponentType<NextPageContext, any, {}>;
router: import("next/dist/client/router").Router;
}>, nextState: Readonly<{}>, nextContext: any): void;
UNSAFE_componentWillUpdate?(nextProps: Readonly<P & PageErrorInitialProps<Record<string, any>> & AppInitialProps & {
Component: NextComponentType<NextPageContext, any, {}>;
router: import("next/dist/client/router").Router;
}>, nextState: Readonly<{}>, nextContext: any): void;
};
getInitialProps: (appContext: import("next/dist/next-server/lib/utils").AppContextType<import("next/dist/client/router").Router>) => Promise<AppInitialProps>;
contextType?: React.Context<any> | undefined;
};
export default withErrorHoC;