Intermediate Level Next js Interview Questions
11. How do you handle redirects and rewrites in Next.js?
Next.js provides a next.config.js file for configuring redirects & rewrites. Redirects send the browser to a new URL, while rewrites map a URL to a different page path.
module.exports = {
async redirects() {
return [
{
source: '/old-path',
destination: '/new-path',
permanent: true,
},
]
},
async rewrites() {
return [
{
source: '/api/:path*',
destination: 'https://api.example.com/:path*',
},
]
},
}
12. How does static site generation (SSG) work in Next.js?
SSG refers to pre-rendering pages at build time as static HTML. Next.js does this by default for pages without data fetching. For pages that fetch data, you can export an async getStaticProps function:
function Blog({ posts }) {
return (
<ul>
{posts.map((post) => (
<li key={post.id}>{post.title}</li>
))}
</ul>
)
}
export async function getStaticProps() {
const res = await fetch('https://.../posts')
const posts = await res.json()
return {
props: {
posts,
},
}
}
export default Blog
getStaticProps fetches data at build time & passes it as props. This allows pages to be pre-rendered with data.
13. How can you handle data fetching in Next.js?
Next.js provides three functions for data fetching:
- getStaticProps: Fetch data at build time for SSG
- getServerSideProps: Fetch data at request time for SSR
- getStaticPaths: Generate static paths for dynamic routes
You can also fetch data client-side using libraries like SWR or React Query for frequently updated data.
14. What is the purpose of the getStaticPaths function in Next JS?
getStaticPaths is used with getStaticProps to generate static pages for dynamic routes. It specifies which paths to render at build time.
export async function getStaticPaths() {
const res = await fetch('https://.../posts')
const posts = await res.json()
const paths = posts.map((post) => ({
params: { id: post.id },
}))
return { paths, fallback: false }
}
getStaticPaths returns an object with a paths array & a fallback flag. paths contains the dynamic routes to pre-render, & fallback controls behavior for paths not specified.
15. What do you understand by code splitting in Next JS?
Code splitting is the process of splitting your code into smaller chunks that can be loaded on demand. Next.js does this automatically by splitting each page into its own JavaScript bundle. This ensures only the code needed for the initial page is loaded, improving performance.
Next.js also supports dynamic imports for splitting code within a page:
import dynamic from 'next/dynamic'
const DynamicComponent = dynamic(() => import('../components/hello'))
function Home() {
return (
<div>
<Header />
<DynamicComponent />
<p>HOME PAGE is here!</p>
</div>
)
}
export default Home
16. What are the different options for styling Next JS apps?
Next.js supports several styling options:
- CSS Modules: Import CSS files as objects to scope styles
- styled-jsx: Write scoped CSS in your components
- Global CSS: Use regular CSS files for global styles
- CSS-in-JS: Use libraries like styled-components or emotion
Which one you use depends on your preferences & project needs. CSS Modules & styled-jsx are built in, while others may require extra setup.
17. What is the purpose of the next.config.js excludes property?
The next.config.js file allows customizing the Next.js build process. The excludes property specifies which files & directories to exclude from the production build. This is useful for omitting large files or directories that aren't needed in production, which can reduce build time & output size.
For example:
module.exports = {
excludes: ['README.md', 'docs', 'examples']
}
This excludes the specified files & directories from the production build.
18. How would you implement server-side rendering (SSR) for a Next JS page?
To implement SSR in Next.js, export an async function called getServerSideProps from your page:
function Page({ data }) {
// Render data...
}
export async function getServerSideProps() {
const res = await fetch('https://.../data')
const data = await res.json()
return { props: { data } }
}
export default Page
getServerSideProps fetches data on each request & passes it as props to the page component. This allows the page to be rendered with up-to-date data on each request.
19. What are Environment Variables in Next JS?
Environment variables allow you to store sensitive information like API keys outside your code. Next.js makes it easy to use environment variables. You can access them in your code like this:
onst apiKey = process.env.API_KEY
To define environment variables, create a .env.local file in the root of your project:
API_KEY=abcdef
By default, Next.js exposes environment variables that start with NEXT_PUBLIC_ to the browser. For server-side only variables, omit that prefix.
20. What is the significance of the _error.js and 404.js files in the pages directory, and how can they be customized for error handling in Next.js?
_error.js is used to create a custom error page. It receives an error prop containing the error details. You can customize this page to display user-friendly error messages.
404.js is used for catching unknown routes & displaying a custom 404 page. You can style this page to maintain brand consistency even for 404 errors.
Both _error.js & 404.js are statically generated like other pages. Customizing them allows full control over the error experience.
Advanced Level Next js Interview Questions
21. What is Docker Image in Next JS?
A Docker image packages up an application with its dependencies into a single unit. This makes it easy to deploy the app consistently across different environments.
You can create a Docker image for a Next.js app by adding a Dockerfile:
FROM node:14
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
EXPOSE 3000
CMD ["npm", "start"]
This Dockerfile installs dependencies, builds the Next.js app & runs it. You can then build & run the Docker image:
docker build -t my-app .
docker run -p 3000:3000 my-app
22. How do you create dynamic routes in Next.js?
Next.js supports dynamic routes using brackets in the page name. For example, pages/blog/[slug].js matches routes like /blog/hello-world.
Inside the page, you can access the route parameter using the useRouter hook:
import { useRouter } from 'next/router'
function BlogPost() {
const router = useRouter()
const { slug } = router.query
return <h1>{slug}</h1>
}
export default BlogPost
To generate the static paths for these routes at build time, export a getStaticPaths async function:
export async function getStaticPaths() {
return {
paths: [
{ params: { slug: 'hello-world' } },
{ params: { slug: 'another-post' } },
],
fallback: false,
}
}
23. Explain the purpose of the getServerSideProps function.
getServerSideProps is an async function you can export from a page to fetch data on each request. It runs on the server & passes fetched data as props to the page component:
function Page({ data }) {
// Render data...
}
export async function getServerSideProps() {
const res = await fetch('https://.../data')
const data = await res.json()
return { props: { data } }
}
export default Page
This allows the page to render with fresh data on each request, which is useful for frequently updated content or personalized pages. However, it's slower than static generation since it runs on each request.
24. How can you implement conditional redirects in Next.js based on certain criteria, such as user authentication status or role?
You can implement conditional redirects using the redirects option in next.config.js:
module.exports = {
async redirects() {
return [
{
source: '/admin/:path*',
has: [
{
type: 'cookie',
key: 'isAdmin',
value: 'true',
},
],
permanent: false,
destination: '/admin/:path*',
},
{
source: '/admin/:path*',
permanent: false,
destination: '/login',
},
]
},
}
This example redirects requests to /admin/:path* to /login unless the isAdmin cookie is set to 'true'. You can customize the logic based on your specific authentication requirements.
25. How can you optimize SEO in a Next.js application?
Some tips for optimizing SEO in Next.js:
- Use meaningful page titles & meta descriptions
- Ensure pages have unique, relevant content
- Use semantic HTML markup
- Optimize images with next/image
- Generate a sitemap.xml with next-sitemap
- Add structured data with next-seo
- Implement proper canonicalization & pagination
- Use getStaticProps for static pages when possible
- Minimize client-side JavaScript for important content
26. How do you manage forms in a Next.js application?
In Next.js, you can manage forms using React's built-in form handling or with the help of third-party libraries like Formik or React Hook Form. Here's a basic example using React's form handling:
import { useState } from 'react'
function ContactForm() {
const [name, setName] = useState('')
const [email, setEmail] = useState('')
const [message, setMessage] = useState('')
const handleSubmit = (e) => {
e.preventDefault()
// Handle form submission, e.g., send data to an API
console.log({ name, email, message })
}
return (
<form onSubmit={handleSubmit}>
<label htmlFor="name">Name:</label>
<input
type="text"
id="name"
value={name}
onChange={(e) => setName(e.target.value)}
/>
<label htmlFor="email">Email:</label>
<input
type="email"
id="email"
value={email}
onChange={(e) => setEmail(e.target.value)}
/>
<label htmlFor="message">Message:</label>
<textarea
id="message"
value={message}
onChange={(e) => setMessage(e.target.value)}
></textarea>
<button type="submit">Submit</button>
</form>
)
}
export default ContactForm
This example uses the useState hook to manage form state & handles form submission with an onSubmit event handler.
27. Explain how to create and use custom hooks in a Next.js application. What are the benefits of custom hooks?
Custom hooks allow you to extract reusable logic from components. They are regular JavaScript functions that can use other hooks. Custom hooks promote code reuse & help keep components focused.
Here's an example custom hook for fetching data:
import { useState, useEffect } from 'react'
function useFetch(url) {
const [data, setData] = useState(null)
const [error, setError] = useState(null)
const [loading, setLoading] = useState(true)
useEffect(() => {
async function fetchData() {
try {
const res = await fetch(url)
const json = await res.json()
setData(json)
setLoading(false)
} catch (error) {
setError(error)
setLoading(false)
}
}
fetchData()
}, [url])
return { data, error, loading }
}
You can then use this hook in any component:
function MyComponent() {
const { data, error, loading } = useFetch('/api/data')
if (loading) return <div>Loading...</div>
if (error) return <div>Error: {error.message}</div>
return <div>{data}</div>
}
Benefits of custom hooks
- Reuse stateful logic between components
- Keep components focused on their main purpose
- Improve code organization & readability
28. How do you handle authentication and authorization in a Next.js application?
Next.js supports multiple authentication patterns. A common approach is to use stateless JWT tokens:
- User submits login credentials
- Server verifies credentials & returns a JWT token
- Client stores the token (e.g., in cookies or local storage)
- Client sends the token with each request
- Server verifies the token & returns the requested data
You can implement this in Next.js API routes & getServerSideProps:
// pages/api/login.js
import jwt from 'jsonwebtoken'
export default function handler(req, res) {
const { username, password } = req.body
// Check username & password, then:
const token = jwt.sign({ username }, 'secret_key')
res.json({ token })
}
// pages/profile.js
import jwt from 'jsonwebtoken'
export async function getServerSideProps(context) {
const { token } = context.req.cookies
const data = jwt.verify(token, 'secret_key')
if (!data) {
return {
redirect: {
destination: '/login',
permanent: false,
},
}
}
return {
props: { data },
}
}
For authorization, you can include user roles in the token & check them when needed.
29. How can you integrate Next.js with GraphQL, and what are the benefits of using GraphQL in a Next.js application?
You can integrate GraphQL into a Next.js app using API routes & libraries like Apollo Client or URQL. First, set up a GraphQL server (e.g., with Apollo Server). Then, create an API route that proxies requests to the GraphQL server:
// pages/api/graphql.js
import { ApolloServer } from 'apollo-server-micro'
import { schema } from '../../graphql/schema'
const apolloServer = new ApolloServer({ schema })
export const config = {
api: {
bodyParser: false,
},
}
export default apolloServer.createHandler({ path: '/api/graphql' })
On the client side, use a GraphQL client library to query the API:
import { useQuery, gql } from '@apollo/client'
const QUERY = gql`
query GetData {
data {
id
name
}
}
function MyComponent() {
const { loading, error, data } = useQuery(QUERY)
if (loading) return <div>Loading...</div>
if (error) return <div>Error: {error.message}</div>
return <div>{data.data.map(d => d.name)}</div>
}
Benefits of using GraphQL in Next.js:
- Efficient data fetching (only request what you need)
- Simpler API development & maintenance
- Strong typing with TypeScript integration
- Excellent tooling & developer experience
30. Discuss the concept of hot module replacement (HMR) in Next.js. How does it enhance the development experience?
Hot Module Replacement (HMR) is a feature that updates modules in the browser at runtime without needing a full refresh. In Next.js, HMR is enabled by default in development mode.
When you save a file, Next.js sends the updated module to the browser, which then replaces the old module with the new one. This preserves application state & allows for faster development iteration.
Next.js supports HMR for the following:
- React components
- Styles (CSS Modules, styled-jsx)
- Static file changes
To take full advantage of HMR, you should ensure your components are correctly lifecycle-managed & can handle being unmounted & remounted.
Benefits of HMR in Next.js:
- Faster development iteration
- Preserve application state between updates
- See changes instantly without full refresh
- Catch errors early without losing context
HMR greatly enhances the development experience by providing near-instant feedback & minimizing context switching.
Conclusion
We hope you have gained some insights on Next JS interview questions through this article. We hope this will help you excel in your interviews and enhance your knowledge of Next JS and related stuff.
You can refer to our guided paths on the Coding Ninjas. You can check our course to learn more about DSA, DBMS, Competitive Programming, Python, Java, JavaScript, etc.
Also, check out some of the Guided Paths on topics such as Data Structure and Algorithms, Competitive Programming, Operating Systems, Computer Networks, DBMS, System Design, etc., as well as some Contests, Test Series, and Interview Experiences curated by top Industry Experts.