skip to Main Content

I am in very critical trouble, let me explain

I am creating a full stack application with next js 13,
I have created an API that is perfectly working in dev(npm run dev) mode but the problem is when I give the build command(npm run build) then it shows the flowing error.
Please anybody bring me out of the problem.
Error Screenshot – https://prnt.sc/VaN1wHifqK_2

 [Error]: Dynamic server usage: Page couldn't be rendered statically because it used `nextUrl.searchParams`. See more info here: https://nextjs.org/docs/messages/dynamic-server-error

Here is my code.
This is the API function for getting users from the database using url searchParams

// /backend/apiControllers/getUsers.js

import prisma from "@/prisma/prismaClient";

export const getUsers = async (request) => {
  const { nextUrl } = request; // here is the problem, this is working for dev mode but not in production build mode.
  const email = nextUrl.searchParams.get("email") || "";
  const phone = nextUrl.searchParams.get("phone") || "";
  const id = nextUrl.searchParams.get("id") || "";

  let queryParam = {};

  if (email) {
    queryParam = {
      where: {
        ...queryParam.where,
        email: {
          equals: email,
          mode: "insensitive",
        },
      },
    };
  }
  if (phone) {
    queryParam = {
      where: {
        ...queryParam.where,
        phone: {
          equals: phone,
        },
      },
    };
  }
  if (id) {
    queryParam = {
      where: {
        ...queryParam.where,
        id: {
          equals: id,
        },
      },
    };
  }

  try {
    const users = await prisma.users.findMany(queryParam);
    return users;
  } catch (error) {
    return { apiMessage: { errorMsg: "Unable to find User details" } };
  }
};

And I have called that function into /app/api/armies/route.js

// /app/api/armies/route.js

import { getUsers } from "@/backend/apiControllers/getUsers";
import { connectDB } from "@/backend/utils/dbConnect";
import { NextResponse } from "next/server";

export const GET = async (request) => {
  try {
    await connectDB();
    const users = await getUsers(request); //called here
    return NextResponse.json(users);
  } catch (error) {
    console.log(error);
    return NextResponse.json({
      apiMessage: { errorMsg: "Internal Server Error, Please try again later" },
    });
  }
};

I have tried the following method also "const url = new URL(request.url);" but the same error, Here is the error screenshot – https://prnt.sc/Z3D317lDQ3CP

import prisma from "@/prisma/prismaClient";

export const getUsers = async (request) => {
  const url = new URL(request.url); // here is the problem, this is working for dev mode but not in production build mode.
  const email = url.searchParams.get("email") || "";
  const phone = url.searchParams.get("phone") || "";
  const id = url.searchParams.get("id") || "";

  let queryParam = {};

  if (email) {
    queryParam = {
      where: {
        ...queryParam.where,
        email: {
          equals: email,
          mode: "insensitive",
        },
      },
    };
  }
  if (phone) {
    queryParam = {
      where: {
        ...queryParam.where,
        phone: {
          equals: phone,
        },
      },
    };
  }
  if (id) {
    queryParam = {
      where: {
        ...queryParam.where,
        id: {
          equals: id,
        },
      },
    };
  }

  try {
    const users = await prisma.users.findMany(queryParam);
    return users;
  } catch (error) {
    return { apiMessage: { errorMsg: "Unable to find User details" } };
  }
};

But again the same error

2

Answers


  1. In Next.js, Every page and route handler are static by default then Next.js will (bail out) opt out to dynamic rendering when using Runtime data such as searchParams or headers. The way Next.js know when dynamic data is used by throwing custom errors and catch them to switch the renderer method. Simply, when you use the request URL (e.g. request.nextUrl) Next.js internall will throw DynamicServerError and catch it at a top-level.

    While generating static pages, Next.js will throw a DynamicServerError if it detects usage of a dynamic function, and catch it to automatically opt the page into dynamic rendering. However, when it’s uncaught, it will result in this build-time error.

    Documentation

    Let’s look at this snippet from your code:

    try {
        const users = await getUsers(request); //called here
        // At the previous line, We used `request.url` / `request.nextUrl`
        // Next.js has thrown a `DynamicServerError`
    
        return NextResponse.json(users);
      } catch (error) {
    
        // Wait!
        // We are trying/catching errors here, so any thrown error withen 
        // the try block will no longer be thrown. As a result, 
        // Next.js no longer knows when you use dynamic data
     
        return NextResponse.json({
          apiMessage: { errorMsg: "Internal Server Error, Please try again later" },
        });
      }
    

    Note*: Read the comments in the code block if you haven’t

    Did you get it?

    How to solve it?

    We have two solutions:

    1. Use dynamic data outside of try/catch statments
    const searchParams = request.nextUrl.searchParams
    
    try {
        const users = await getUsers({ searchParams });
        return NextResponse.json(users);
        // ...
    

    This way, Next.js will throw its errors and catch them without a stumbling block.

    1. Re-throw Next.js errors:

    You can also, catch errors and rethrow Next.js errors to handle them. Next.js provides some utilities to know the error.

    import { isDynamicServerError } from "next/dist/client/components/hooks-server-context";
    
    // ...
    
    try {
      const {nextUrl} = request;
    } catch (error) {
      if (isDynamicServerError(error)) {
        throw error;
      }
    
      // handle other errors
    }
    

    When using some of Next.js functions inside try you need to re-throw them. for example, isNotFoundError for notFound(), isRedirectError for redirect.

    import { isStaticGenBailoutError } from "next/dist/client/components/static-generation-bailout";
    import { isNotFoundError } from "next/dist/client/components/not-found";
    import { isRedirectError } from "next/dist/client/components/redirect";
    import { isDynamicServerError } from "next/dist/client/components/hooks-server-context";
    
    Login or Signup to reply.
  2. in next.js, in general, if you reference a dynamic variable in a page, that page becomes dynamic. Because, if you think about it, useSearchParams reads and manipulates the URL’s query parameters in the browser. This means the content or behavior of the page can change without a full page reload, based solely on changes to the URL’s query string. That is why,this page cannot be rendered as static

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search