Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reading cookies in _document.js (nextjs) works on localhost but not in production. #201

Open
metinvio opened this issue Jun 4, 2024 · 3 comments

Comments

@metinvio
Copy link

metinvio commented Jun 4, 2024

On localhost it just works perfect. This is my cookies component and how i set cookies using react-cookies-consent:


// components/ExtendedCookieConsent.js
import { useRouter } from "next/router";
import React, { useState, useEffect } from "react";
import CookieConsent, { Cookies } from "react-cookie-consent";

const ExtendedCookieConsent = () => {
  const [appsflyerConsent, setAppsflyerConsent] = useState(true);
  const [mixpanelConsent, setMixpanelConsent] = useState(true);
  const router = useRouter();



  const handleAccept = () => {
    Cookies.set(
      "myAppCookieConsent",
      { appsflyer: appsflyerConsent, mixpanel: mixpanelConsent },
      {
        expires:
          appsflyerConsent === true && mixpanelConsent === true ? 365 : 1,
        path: "/",
        domain: "mydomain.com",
        sameSite: "Lax",
        secure: true,
      }
    );
    router.reload();
  };

  const handleDecline = () => {
    Cookies.set(
      "myAppCookieConsent",
      { appsflyer: false, mixpanel: false },
      {
        expires: 1,
        path: "/",
        domain: "mydomain.com",
        sameSite: "Lax",
        secure: true,
      }
    );
    router.reload();
  };

  return (
    <CookieConsent
      location="bottom"
      buttonText="Speichern"
      declineButtonText="All ablehnen"
      cookieName="myAppCookieConsent"
      style={{
        background: "#454545cf",
        backdropFilter: "blur(5px)",
        WebkitBackdropFilter: "blur(5px)",
        padding: "10px",
        display: "table-column",
      }}
      declineButtonStyle={{
        background: "#45454500",
        borderRadius: "5px",
        color: "white",
        cursor: "pointer",
      }}
      buttonStyle={{
        background: "#51d198",
        borderRadius: "5px",
        color: "#1b1b1b",
        fontWeight: "bold",
        cursor: "pointer",
      }}
      enableDeclineButton
      onAccept={handleAccept}
      onDecline={handleDecline}
    >
      <div>...</div>
    </CookieConsent>
  );
};

export default ExtendedCookieConsent;

And this is how I read them (nookies.js) after user makes choice and inits a refresh of the page:

// pages/_document.js
import Document, { Html, Head, Main, NextScript } from "next/document";
import { parseCookies } from "nookies";

class MyDocument extends Document {
  static async getInitialProps(ctx) {
    const initialProps = await Document.getInitialProps(ctx);

    // Parsing cookies from the request
    const cookies = parseCookies(ctx);
    const cookieConsent = cookies.myAppCookieConsent
      ? JSON.parse(cookies.myAppCookieConsent)
      : {};
    console.log("CookieConsent : " + JSON.stringify(cookieConsent, 0, 2));
    return { ...initialProps, cookieConsent };
  }

  render() {
 
  }
}

export default MyDocument;

Hosting: Vercel
Libs:
"next": "^14.0.4",
"react-cookie-consent": "^9.0.0",
"nookies": "^2.5.2",

@Mastermindzh
Copy link
Owner

Hey,

Cookies are a client-only thing, can you try setting the use-client flag on the files?

Adding 'use client' at the top of the file should do:

'use client'

import * from ...

@metinvio
Copy link
Author

metinvio commented Jun 4, 2024

Thank you very much for the quick response but can you explain in more detail. I'm new to web dev.🙈

I try to read the cookies in order to conditionally run scripts in _document.js' element - doesn't _document.js run on server?

@Mastermindzh
Copy link
Owner

Sure,

There's 2 reasons:

  1. When I developed this component, Next.js didn't really exist yet, it might have been out for like half a year or so but wasn't ever really a target for the lib until much later.
  2. Server-side cookies checks are much more expensive (in dev time) than loading a part of the UI client-side only, so I (nor others) never rewrote the package to support server-side rendering.

Why not make it server-side? well....

Some cookies, like we use in the cookiebanner, are strictly a client-side thing so it's impossible to detect this particular type of cookie on the server and pre-render the cookiebanner.

Think of it like this:

  • The cookie bar is used to ask the user whether he/she wants to allow cookies that impact their privacy
  • This is checked locally on their machine, and the running code then changes to fit their needs
    • if they select "no", no user data should be sent to the server anonymously/automatically
    • if "yes" then it's fine to use cookies to track the user

If we were to render it on the server side then we'd need to know something about the user to verify who they are, so one could argue we are storing sensitive data (or at least identifiable data, probably even before login).

Lots of extra things to take care off, whilst rendering this one particular component on the client-side doesn't incur much cost at all.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants