Short answer: Yes, you can use both. They serve different purposes and can be used in the same application.
According to Next.js documentation:
Next.js uses the App component to initialize pages.
To override this behavior, create the
./pages/_app.jsfile and override the App class.
and
Pages in Next.js skip the definition of the surrounding document's markup. For example, you never include
<html>,<body>, etc. To override that default behavior, you must create a file at./pages/_document.js, where you can extend the Document class.
Note: _document.js is only rendered on the server side and not on the client side. Therefore, event handlers like onClick will not work.
In Next.js, _app.js and _document.js are two special files used for customizing the default structure and behavior of your Next.js application.
_app.js
The _app.js file initializes all pages. You can use it to maintain consistent page layouts across pages or preserve page state (such as login status). It is also suitable for adding global CSS styles.
When creating a custom _app.js, you must export a React component that receives specific props, such as Component and pageProps. The Component prop represents the page content, while pageProps is an object containing props for initializing the page.
For example, to include the same navigation bar and footer across all pages, you can implement:
jsximport React from 'react'; import Navbar from '../components/Navbar'; import Footer from '../components/Footer'; // The Component prop represents the current page function MyApp({ Component, pageProps }) { return ( <> <Navbar /> <main> <Component {...pageProps} /> </main> <Footer /> </> ); } export default MyApp;
_document.js
The _document.js file allows you to customize the <html> and <body> tags and the document structure. This file only runs during server-side rendering, so avoid adding application logic here.
_document.js is used to modify the document content for server-side rendering. This is typically needed when adding server-side rendering code snippets (such as custom fonts or <meta> tags) or when adding additional attributes to the <html> and <body> tags.
A custom _document.js implementation appears as follows:
jsximport Document, { Html, Head, Main, NextScript } from 'next/document'; class MyDocument extends Document { render() { return ( <Html lang="en"> <Head> {/* Place `<link>` or `<meta>` tags here */} </Head> <body> {/* You can add additional elements to the body here, but typically you only need */} <Main /> {/* <-- Renders the application content */} <NextScript /> {/* <-- Renders Next.js core scripts */} </body> </Html> ); } } export default MyDocument;
In _document.js, the <Main /> component is replaced with your application's page content, and <NextScript /> is required for Next.js core scripts.
Summary
- Use
_app.jsto add layout components or global state management (e.g., Redux or Context API). - Use
_document.jsto customize server-side rendering document structure and tags, such as adding custom fonts, analytics code, or additional attributes to<html>and<body>tags.
Both files are optional. If your application does not require modifications to the default behavior, you can omit them entirely.