NextJS
Intermediate FAQs

Here are some intermediate level Next.js interview questions with their corresponding answers and examples. I'll include visuals, Unicode, and diagrams where possible to enhance the clarity of the concepts.


1. What is Dynamic Import in Next.js? How does it improve performance?

  • Answer: Dynamic imports allow you to load JavaScript modules on-demand, which helps to split the code into smaller bundles. This improves performance by loading only the necessary code for each page instead of the entire app.

  • Example:

    import dynamic from 'next/dynamic';
     
    const DynamicComponent = dynamic(() => import('../components/HeavyComponent'), {
      loading: () => <p>Loading...</p>, // Placeholder while loading
    });
     
    function Page() {
      return (
        <div>
          <h1>Page with Dynamic Import</h1>
          <DynamicComponent />
        </div>
      );
    }
     
    export default Page;
  • Performance Benefits:

    • 🗂 Code Splitting: Dynamically imports only necessary code.
    • Improved Load Times: Reduces initial bundle size.
    • 🔁 Faster Navigation: Loads additional code as users navigate through the site.

2. How does getInitialProps differ from getStaticProps and getServerSideProps?

  • Answer:

    • getInitialProps is a legacy method used to fetch data on both the server and client side. It's more flexible but less efficient because it runs on every page navigation.
    • getStaticProps and getServerSideProps are more modern approaches, introduced to optimize static and server-rendered pages.
  • 🔄 Differences:

    FunctionWhen It RunsUse Case
    getInitialPropsOn both server and clientLegacy; for data fetching on both sides
    getStaticPropsAt build time (SSG)Static pages with infrequent data updates
    getServerSidePropsOn every request (SSR)Dynamic data that needs to be up-to-date for each request

3. What is next.config.js and how do you use it?

  • Answer: The next.config.js file is used to configure various settings in a Next.js application, such as setting up environment variables, enabling experimental features, configuring redirects, and handling webpack configurations.

  • Example:

    // next.config.js
    module.exports = {
      env: {
        API_URL: 'https://api.example.com',
      },
      async redirects() {
        return [
          {
            source: '/old-route',
            destination: '/new-route',
            permanent: true,
          },
        ];
      },
      webpack(config, { isServer }) {
        // Custom webpack config
        if (!isServer) {
          config.resolve.fallback.fs = false; // To prevent 'fs' errors in client-side code
        }
        return config;
      },
    };
  • 🛠 Common Uses:

    • Custom Webpack 🖧: Add custom plugins or modify configurations.
    • Environment Variables 🌍: Easily define and use environment variables.
    • Redirects & Rewrites ➡️: Handle URL redirections or rewrites.

4. What is the difference between Client-Side Rendering (CSR) and Server-Side Rendering (SSR) in Next.js?

  • Answer:

    • CSR: JavaScript runs on the client’s browser, rendering the application entirely on the client-side. The HTML delivered is minimal, and the content is fetched and rendered after the page loads.
    • SSR: The HTML is rendered on the server and sent to the client, so users see the content immediately upon request.
  • Comparison:

    Rendering TypeServer-side Rendering (SSR)Client-side Rendering (CSR)
    Initial LoadFasterSlower (more waiting for data)
    SEOBetterLimited
    InteractivityDelayed until hydrationImmediate
  • Example: SSR in Next.js:

    export async function getServerSideProps() {
      const res = await fetch('https://api.example.com/data');
      const data = await res.json();
      return { props: { data } };
    }

5. How do you handle API Caching in Next.js?

  • Answer: Caching can be handled using various strategies like HTTP cache-control headers or utilizing Incremental Static Regeneration (ISR).

  • Example using Cache-Control headers in API routes:

    // pages/api/posts.js
    export default function handler(req, res) {
      res.setHeader('Cache-Control', 's-maxage=10, stale-while-revalidate=59');
      res.status(200).json({ posts: [] });
    }
  • Explanation:

    • s-maxage=10: The response will be cached for 10 seconds by the server.
    • stale-while-revalidate=59: The cached response can still be served while a new one is fetched in the background.

6. How does Image Optimization work in Next.js?

  • Answer: Next.js has a built-in image optimization feature that automatically optimizes images by resizing, lazy-loading, and serving the correct format (like WebP) based on the client’s browser capabilities.

  • Example:

    import Image from 'next/image';
     
    function Page() {
      return (
        <div>
          <Image
            src="/images/photo.jpg"
            alt="Example image"
            width={500}
            height={500}
          />
        </div>
      );
    }
     
    export default Page;
  • Benefits:

    • 📉 Reduced file size for faster load times.
    • 🖼 Automatic resizing for different screen sizes.
    • 💤 Lazy loading for offscreen images, improving performance.

7. Explain how Next.js API Routes work. How can you handle different HTTP methods?

  • Answer: Next.js allows you to create API routes using the /pages/api directory. Each file inside this directory is mapped to a corresponding endpoint. You can handle different HTTP methods (GET, POST, PUT, DELETE) using req.method.

  • Example:

    export default function handler(req, res) {
      if (req.method === 'GET') {
        // Handle GET request
        res.status(200).json({ message: 'GET request' });
      } else if (req.method === 'POST') {
        // Handle POST request
        res.status(201).json({ message: 'POST request' });
      } else {
        res.setHeader('Allow', ['GET', 'POST']);
        res.status(405).end(`Method ${req.method} Not Allowed`);
      }
    }
  • 💻 HTTP Methods:

    • GET 🟢: Fetch data.
    • POST 🟡: Submit new data.
    • PUT 🔵: Update existing data.
    • DELETE 🔴: Remove data.

8. What is Middleware in Next.js, and how can it be used?

  • Answer: Middleware in Next.js allows you to run code before a request is completed. It is used for tasks like authentication, logging, and URL rewriting. Middleware is defined in the middleware.js file at the root of your Next.js application.

  • Example:

    // middleware.js
    import { NextResponse } from 'next/server';
     
    export function middleware(req) {
      const url = req.nextUrl;
      if (url.pathname.startsWith('/dashboard')) {
        // Check if user is authenticated
        const token = req.cookies.get('auth-token');
        if (!token) {
          return NextResponse.redirect('/login');
        }
      }
      return NextResponse.next();
    }
  • Benefits:

    • Access Control 🔑: Implement access restrictions and authentication.
    • Logging 📊: Track user activity and requests.
    • URL Rewriting 🔄: Dynamically change URLs.

9. What is the role of the _document.js file in Next.js?

  • Answer: The _document.js file is used to customize the server-rendered HTML document. It allows you to modify the <html>, <head>, and <body> tags.

  • Example:

    // pages/_document.js
    import { Html, Head, Main, NextScript } from 'next/document';
     
    export default function MyDocument() {
      return (
        <Html>
          <Head>
            <link rel="stylesheet" href="/custom.css" />
          </Head>
          <body>
            <Main />
            <NextScript />
          </body>
        </Html>
      );
    }
  • Usage:

    • Inject custom fonts, stylesheets, or meta tags into the HTML document.
    • Modify the

structure of the root HTML.


10. How do you enable TypeScript in a Next.js project?

  • Answer: Next.js has built-in support for TypeScript. You can enable TypeScript by adding a tsconfig.json file to your project. When you run the development server, Next.js will automatically detect and install TypeScript dependencies.

  • Steps:

    1. Create a tsconfig.json file:
      {
        "compilerOptions": {
          "target": "es5",
          "module": "esnext",
          "strict": true,
          "jsx": "preserve",
          "moduleResolution": "node"
        },
        "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
        "exclude": ["node_modules"]
      }
    2. Rename your .js files to .ts or .tsx.

Conclusion

These intermediate-level Next.js questions will help you better understand the framework's deeper concepts and features. By mastering these topics, you'll be well-prepared for more advanced development and architecture-related discussions.