Skip to content

Conversation

greg2012201
Copy link
Contributor

Hello! @andreizanik @joaopcm
I took over this PR #86 and successfully re-implemented smart imports to reduce dependency on window.
We now check options to determine if the function is being called on the client or server.
Additionally, we validate the presence of the window object to identify the render phase of the client component:

	
const getFn = (fnName: keyof typeof clientCookies, options?: OptionsType) => {
  if (isClientSide(options)) {
    if (getRenderPhase() === 'server') {
      // to prevent crash caused by missing window.document during server rendering phase
      return;
    }
    return clientCookies[fnName];
  }

  return serverCookies[fnName];
};

This step is necessary because, even if the function is designated for the client, Next.js attempts to use it during the server phase,
where objects like document are unavailable. This adjustment resolves environment-specific (server/client) errors.

I also encountered some issues with type compatibility. There was a type mismatch in NextRequest/NextResponse imported from next/server.
These class declarations include an [INTERNALS] property of the symbol type,
which was required by our library but missing in the Next.js application when exported from next/server.
Although I haven’t identified the root cause, defining custom interfaces has resolved the issue:

interface NextCookiesRequest extends Request {
  get cookies(): RequestCookies;
}

interface NextCookiesResponse extends Response {
  get cookies(): ResponseCookies;
}

All tests have passed, and I have manually tested the functionality with Next.js v15.0.1. Everything appears to work correctly.

Please review the code and conduct your own tests to ensure readiness for release.

joaopcm and others added 24 commits October 21, 2024 19:16
-  replaced  and  with  and  for better clarity and alignment with Next.js conventions
-  simplified cookie transformation and validation functions to use
-  removed redundant type definitions and moved relevant types to a centralized file
-  improved error handling by formatting error messages for better readability
-  deleted unused  file to reduce code duplication and maintain consistency across the codebase
@greg2012201 greg2012201 changed the title feat: add Next.js 15+ support feat: add Next.js 15+ support (continuation) Oct 29, 2024
Copy link
Contributor

@joaopcm joaopcm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is looking great to me!

I will stress test it to make sure it is properly handling all the cases as well! Great job! 🙌🏻

src/index.ts Outdated

const getFn = (fnName: keyof typeof clientCookies, options?: OptionsType) => {
if (isClientSide(options)) {
if (getRenderPhase() === 'server') {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

import { getCookie } from 'cookies-next'

export const TestComponent = () => {
    const isActive = getCookie('active');
    
    return (
        <div>{isActive ? 'active': 'not active'}</div>
    );
}

it looks like we will have a difference between what the server and the client render.

Because getCookie always returns undefined on the server phase.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, although the current version most likely has the same behavior

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In my implementation, we simply return undefined when a function is designated for client-side use, and the client component calling it is being pre-rendered.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's worth mentioning that hasCookie always returns a boolean. In a client component during the server phase, it returns false instead of undefined. In my opinion, having a consistent return type is important for hasCookie.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see the issue now. One part of the problem is the mismatch between server and client. Additionally, if we use a function from the cookies-next import, we also encounter type-related issues:

Do you have any ideas on how to fix this?

image

@andreizanik
Copy link
Owner

@greg2012201 Thanks!

I will stress test it to make sure it is properly handling all the cases as well!

@joaopcm do you have any results?

@ck-euan
Copy link

ck-euan commented Oct 31, 2024

Thank you all for this it looks great :)

However, I ran into this error while using it in my project:

Error: Switched to client rendering because the server rendering errored:

document is not defined

This happens for me when using getCookie from cookies-next/client in a client component.

@greg2012201
Copy link
Contributor Author

greg2012201 commented Oct 31, 2024

Thank you all for this it looks great :)

However, I ran into this error while using it in my project:

Error: Switched to client rendering because the server rendering errored:

document is not defined

This happens for me when using getCookie from cookies-next/client in a client component.

@ck-euan You're absolutely right; I missed that and forgot to add the render phase check in the client-side functions. I've pushed a fix for this.

@andreizanik @joaopcm Please test my changes again. I believe we're almost done.

Co-authored-by: Andrei Zanouski <andreizaniK@gmail.com>
@greg2012201
Copy link
Contributor Author

After my changes, we still encounter issues. Please refer to: #87 (comment)

I'm considering whether we should implement hooks for the client side. We could maintain the old functions in asynchronous versions for the server side, along with hooks for the client side, all exported from a single index.ts file.

What do you guys think?

@andreizanik
Copy link
Owner

andreizanik commented Nov 4, 2024

After my changes, we still encounter issues. Please refer to: #87 (comment)

I'm considering whether we should implement hooks for the client side. We could maintain the old functions in asynchronous versions for the server side, along with hooks for the client side, all exported from a single index.ts file.

What do you guys think?

May be in next PR?

This PR looks good to me

@greg2012201
Copy link
Contributor Author

greg2012201 commented Nov 4, 2024

After my changes, we still encounter issues. Please refer to: #87 (comment)

I'm considering whether we should implement hooks for the client side. We could maintain the old functions in asynchronous versions for the server side, along with hooks for the client side, all exported from a single index.ts file.

What do you guys think?

May be in next PR?

This PR looks good to me

@andreizanik I've added the last two commits to this PR. I updated the export functions to narrow down return types and updated the documentation to explain how to use cookies-next in client components without causing mismatch errors.

Please check if everything works for you!

PS: We can work on hooks in another PR.

@andreizanik andreizanik merged commit 694d359 into andreizanik:master Nov 8, 2024
@andreizanik
Copy link
Owner

Today I published a new version.
Thanks @joaopcm @greg2012201 and everyone who was involved

@greg2012201 greg2012201 mentioned this pull request Nov 19, 2024
@bombillazo
Copy link

How can we make this work with Next.js Pages router as it was in v4?

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

Successfully merging this pull request may close these issues.

5 participants