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

Example for NextJS 14 and Tailwind with App Router #19

Closed
gygabyte017 opened this issue Nov 9, 2023 · 14 comments
Closed

Example for NextJS 14 and Tailwind with App Router #19

gygabyte017 opened this issue Nov 9, 2023 · 14 comments

Comments

@gygabyte017
Copy link

Hi, do you mind updating (or adding) the examples with nextjs+tailwind, styled and unstyled, using the new App Router in v14? I'm struggling about configuring the new layout.tsx, I managed to use Primereact OR Tailwind, but not both together.

Thank you
Regards

@melloware
Copy link
Member

Issue has been asked under the Free Sakai React template as well: primefaces/sakai-react#47

And open issue: primefaces/primereact#5127

@nicolasGallegos
Copy link

Has Next14 been able to integrate with Prime React and Tailiwind?

@robsoncombr
Copy link

+1

@BanDroid
Copy link

i got news. nextjs 13+ with app router and tailwind could work together without the layer thing. just need to import the css theme.css below the globals.css in layout file. i figure this out after i got no styling at all even after following the tailwind instruction, turns out i got it working after switching these line.

// this is the wrong order
import "primereact/resources/themes/md-dark-indigo/theme.css";
import "./globals.css";
// this is the right order
import "./globals.css";
import "primereact/resources/themes/md-dark-indigo/theme.css";

@amurilo
Copy link
Contributor

amurilo commented Aug 13, 2024

import "primereact/resources/themes/md-dark-indigo/theme.css";

Hey man, nice! Can you share a complete configuration for this? Do we still need the PrimeReactProvider?

@BanDroid
Copy link

BanDroid commented Aug 13, 2024

import "primereact/resources/themes/md-dark-indigo/theme.css";

Hey man, nice! Can you share a complete configuration for this? Do we still need the PrimeReactProvider?

basically, no. The provider only hold state for components and themes, but the css only apply the style, and if the style applied in incorrect order, the tailwind will reset the primereact style cause it is tailwind behavior to reset any styling that applies before them.

also, no need extra configuration, just import the css theme in correct order. altough, i haven't try with toggling theme with this solution, maybe you could override the style with dynamic import or something.

@melloware
Copy link
Member

@BanDroid i would love if you wanted to submit a PR for this example here in the examples folders because this gets asked a lot?

@BanDroid
Copy link

BanDroid commented Aug 13, 2024

@BanDroid i would love if you wanted to submit a PR for this example here in the examples folders because this gets asked a lot?

others need to confirm if my solution works or not, it works with mine, but i'm not sure if this is working with someone else.

@amurilo
Copy link
Contributor

amurilo commented Aug 13, 2024

The only way I managed to work is by adding preflight as false in my tailwind.config.ts but this is a huge nuclear bomb so is not a solution but a workaround.

const config: Config = {
  corePlugins: {
    preflight: false,
  }

I have no idea but this layers in global.css are doing jack.

@layer twbase, primereact, twutilities;

@import 'primereact/resources/themes/lara-light-indigo/theme.css' layer(primereact);

@layer twbase {
 @tailwind base;
}

@layer twutilities {
 @tailwind components;
 @tailwind utilities;
}

The issue itself is with the tailwind, not primereact because if you remove the tailwind either by disabling the preflight or by removing the layers and leaving just your theme in your global.css, it suddenly works.

@BanDroid, can you share a stackblitz so we can take a look? ❤️

@amurilo
Copy link
Contributor

amurilo commented Aug 15, 2024

SO... I was able to find a weird solution but I have NO IDEA why it works, I really don't understand.

The usual global.css

@layer tailwind-base, primereact, tailwind-utilities;

/* 
I was having caching issues, you don't really need this thing.
@import 'primereact/resources/themes/saga-blue/theme.css' layer(primereact);  */

@layer tailwind-base {
  @tailwind base;
}

@layer tailwind-utilities {
  @tailwind components;
  @tailwind utilities;
}

AND...

Bro, I don't understand why.

Just add a second import with the actual theme you want to use in your layout.tsx

import "./globals.css";
import 'primereact/resources/themes/saga-blue/theme.css';

You can go either way with provider or not.

<PrimeReactProvider>
    {children}
</PrimeReactProvider>

Is this what you meant @BanDroid? We basically have to add the theme twice, one "dummy" and another one you actually want to use.

edit: apparently the reason why I needed two of the imports is that you don't really need the import on the global.css like the documentation suggests. weird.

Adding to the layout.tsx alone sort of works, I did a bunch of testing and I couldn't find anything wrong with it. Which is great.

@BanDroid
Copy link

BanDroid commented Aug 15, 2024

Bro, I don't understand why.

Just add a second import with the actual theme you want to use in your layout.tsx

import "./globals.css";
import 'primereact/resources/themes/saga-blue/theme.css';

You can go either way with provider or not.

<PrimeReactProvider>
    {children}
</PrimeReactProvider>

Is this what you meant @BanDroid? We basically have to add the theme twice, one "dummy" and another one you actually want to use.

yes, this is what i mean, you dont exactly need to import primereact in globals.css, cause primereact classes and tailwind classes have different prefixes, it will be different case if you also use primefaces (seriously, why? 2 utility library?)

so the logic would be like this

tailwind (will reset browser style) -> primereact (will add primereact style)

you could still use tailwind utility and color because the classname prefix are different, so just make sure globals.css (tailwind) will have to come first then primereact the second import.

you could also use primereact utility together with tailwind using dynamic value.

className="bg-[var(--my-primereact-color)]"

@melloware
Copy link
Member

Thanks to @BanDroid and @meowzhin a new sample has been added: https://github.com/primefaces/primereact-examples/tree/main/nextjs-app-router-styled-tailwind

@VytautasLozickas
Copy link

VytautasLozickas commented Nov 21, 2024

Trying to use the unstyled version like this:

<PrimeReactProvider
    value={{
        unstyled: true,
        pt: Tailwind,
        ptOptions: { mergeSections: true, mergeProps: true, classNameMergeFunction: twMerge },
    }}>
    {children}
</PrimeReactProvider>

Causes an error when trying to pass twMerge into classNameMergeFunction:

[ Server ] Error: Functions cannot be passed directly to Client Components unless you explicitly expose it by marking it with "use server". Or maybe you meant to call this function rather than return it.
  {mergeSections: true, mergeProps: true, classNameMergeFunction: function callTailwindMerge}
                                                                  ^^^^^^^^^^^^^^^^^^^^^^^^^^

@BanDroid
Copy link

Trying to use the unstyled version like this:

<PrimeReactProvider
    value={{
        unstyled: true,
        pt: Tailwind,
        ptOptions: { mergeSections: true, mergeProps: true, classNameMergeFunction: twMerge },
    }}>
    {children}
</PrimeReactProvider>

Causes an error when trying to pass twMerge into classNameMergeFunction:

[ Server ] Error: Functions cannot be passed directly to Client Components unless you explicitly expose it by marking it with "use server". Or maybe you meant to call this function rather than return it.
  {mergeSections: true, mergeProps: true, classNameMergeFunction: function callTailwindMerge}
                                                                  ^^^^^^^^^^^^^^^^^^^^^^^^^^

the file where you create the twMerge function, add the "use client" directives, because your provider is client-component, but this twMerge function is in server, i'm not sure how you import the twMerge

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

7 participants