next.jsnext.js13app-router

Client Side component is being server rendered by NextJS 13 and giving an 'alert' not defined error


I am creating a web application using nextjs 13 and App router.

The folder structure is as follows:

All pages that import the ReportForm.tsx component (imported from /components/Reportform.tsx' are marked as 'use client' and test/page does not import report-form but when I navigate to it I am given the following error

 ⨯ components/forms/ReportForm.tsx (63:2) @ alert
 ⨯ ReferenceError: alert is not defined
    at Report (./components/forms/ReportForm.tsx:51:5)
  61 | const Report = ({ type, initialValues }: ReportProps) => {
  62 |   "use client";
> 63 |   alert("reading report");
     |  ^
  64 |   const { reportData } = useReportContext();
  65 |   if (!reportData) {
  66 |     alert("report Data not found");
 ⨯ components/forms/ReportForm.tsx (63:2) @ alert

I tried adding a "use client" within the component even though it already exists at the start of the file. I expect the nextjs compiler to not try server rendering the client side form component - which it was not trying before and I am not sure what changed. PS I have already tried a lot of redoing as well as folder restructuring.

The one reasoning I thought it is using to attempt server-side compilation is because I added a new button to the form for republishing an existing report. But I don't understand how that would change things since before this it was never server side compiled.


Solution

  • As i can see from your error message, you trying to use alert() while component is still mounting. But you can use alert() only after component is mounted. You can use Effect Hook:

    useEffect(() => {
        alert("reading report");
    }, []);
    

    By using this Hook, you tell React that your component needs to do something after render

    The issue is how React handle rendering.

    In React, components go through a lifecycle:

    1.Rendering Phase: During this phase, no side effects (like alert() or data fetching) should be performed because the component isn't yet "mounted" in the DOM.

    2.Commit Phase: After rendering, React commits the component to the DOM. At this point, side effects are safe to perform.

    If you need to trigger an action (like alert() or fetch api) right after the component is mounted in the browser, you need to use React's useEffect hook. This hook runs after the component has been rendered and committed to the DOM, ensuring it's safe to perform side effects.

    Without useEffect, when you call alert() it will execute during the rendering phase, which cause issues because React isn't finished mounting the component yet.

    When using Next.js, there's an additional layer of complexity - server-side rendering (SSR) and client-side rendering (CSR). Server components render on the server and don't have access to the browser environment (e.g., window, alert, etc.). Client components are rendered in the browser and can use those features. And if you put "use client" at the top of your component and before all imports, it will be client side component even if page, where you render this component, is server side.