Skip to content

Conversation

@Tobi696
Copy link

@Tobi696 Tobi696 commented Mar 28, 2025

Starter template based upon new "blank" template with nativewind v4 installed

@vercel
Copy link

vercel bot commented Mar 28, 2025

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
solito-app ✅ Ready (Inspect) Visit Preview 💬 Add feedback Mar 28, 2025 3:38pm
1 Skipped Deployment
Name Status Preview Comments Updated (UTC)
solito ⬜️ Ignored (Inspect) Visit Preview Mar 28, 2025 3:38pm

@Tobi696
Copy link
Author

Tobi696 commented Mar 28, 2025

hey @nandorojo can you check this please?

@nandorojo
Copy link
Owner

Hey thank you!

Really appreciate the work here.

I think my ideal case is to add a "how to use nativewind" guide to the docs and have this alongside the blank template, just so that it's easier to upgrade them all...any shot you'd be open to documenting what steps one should take to install nativewind + tailwind on top of the blank template?

more than happy to merge that.

@nandorojo
Copy link
Owner

PS sorry I missed this earlier.

Copy link

@redkean redkean left a comment

Choose a reason for hiding this comment

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

this has mismatched packages such as:

  • @types/react@^18.2.21 and @types/react@~18.3.12
  • typescript@^5.2.2 and typescript@~5.3.3

@Tobi696
Copy link
Author

Tobi696 commented Oct 8, 2025

It also has a problem with CLS on the web. IDK if that is even fixable, because of the way how CSS and classes are applied in nativewind. I thought, the tailwind config's contents property would avoid that by pre-generating the css classes used, but either something is wrong in my config here, or it just doesn't work like that with nativewind.

@nandorojo I saw you have a 0 CLS on https://beatgig.com, what is the stack behind that? Do you use nativewind there?

@nandorojo
Copy link
Owner

I'm guessing something is up because it should work without a layout shift with tailwind

@Tobi696
Copy link
Author

Tobi696 commented Oct 8, 2025

Would be really cool if we found the underlying problem for the CLS...
I have a feeling it is because the CSS isn't generated at build time and then the classes + styles are late-applied via JS.
You can check yourself, my project is https://highratedhotels.com, when checking the performance tab, it has CLS of 0.56.

apps/next/tailwind.config.js

/** @type {import('tailwindcss').Config} */
module.exports = {
  content: [
    './app/**/*.{js,jsx,ts,tsx}',
    '../../packages/**/*.{js,jsx,ts,tsx}',    <- I have a feeling that this doesn't work as expected
  ],
  presets: [require('nativewind/preset')],
  important: 'html',

  ...require("../../packages/app/tailwind/shared-config"),
}

For further info, I use next.js in a standalone docker build, SSR not SSG. Next.js with app router of course, as you see in the PR contents.

@vercel
Copy link

vercel bot commented Oct 8, 2025

@Tobi696 is attempting to deploy a commit to the Fernando Rojo's projects Team on Vercel.

A member of the Team first needs to authorize it.

@redkean
Copy link

redkean commented Oct 9, 2025

Would be really cool if we found the underlying problem for the CLS... I have a feeling it is because the CSS isn't generated at build time and then the classes + styles are late-applied via JS. You can check yourself, my project is https://highratedhotels.com, when checking the performance tab, it has CLS of 0.56.

apps/next/tailwind.config.js

/** @type {import('tailwindcss').Config} */
module.exports = {
  content: [
    './app/**/*.{js,jsx,ts,tsx}',
    '../../packages/**/*.{js,jsx,ts,tsx}',    <- I have a feeling that this doesn't work as expected
  ],
  presets: [require('nativewind/preset')],
  important: 'html',

  ...require("../../packages/app/tailwind/shared-config"),
}

For further info, I use next.js in a standalone docker build, SSR not SSG. Next.js with app router of course, as you see in the PR contents.

your issue stems from relying on native styling which is still in JS.
look at this demo on your site

output_video.mp4

EDIT:
did you apply a css reset in your global.css?

@Tobi696
Copy link
Author

Tobi696 commented Oct 9, 2025

Thanks for helping.
No css reset in my global.css, here's the full content:

@tailwind base;
@tailwind components;
@tailwind utilities;

@layer base {
    :root {
        --background: 177 30% 95%;
        --foreground: 0 0% 3.9%;
        --card: 0 0% 100%;
        --card-foreground: 0 0% 3.9%;
        --popover: 0 0% 100%;
        --popover-foreground: 0 0% 3.9%;
        --primary: 177 100% 28%;
        --primary-light: 177 98% 40%;
        --primary-foreground: 0 0% 98%;
        --secondary: 0 0% 20%;
        --secondary-foreground: 0 0% 9%;
        --muted: 0 0% 96.1%;
        --muted-foreground: 0 0% 45.1%;
        --accent: 0 0% 96.1%;
        --accent-foreground: 0 0% 9%;
        --destructive: 0 84.2% 60.2%;
        --warning: 30 84.2% 60.2%;
        --warning-foreground: 0 0% 98%;
        --destructive-foreground: 0 0% 98%;
        --border: 0 0% 89.8%;
        --input: 0 0% 89.8%;
        --ring: 0 0% 3.9%;

        --chart-1: 12 76% 61%;
        --chart-2: 173 58% 39%;
        --chart-3: 197 37% 24%;
        --chart-4: 43 74% 66%;
        --chart-5: 27 87% 67%;
        --radius: 0.5rem;
        --dark: #0E0D00;
        --gold-light: #FDF7BC;
        --gold: #CFAA29;
        --success: 123 46% 34%;
        --rating: 43 100% 50%;
        --sidebar-background: 0 0% 98%;
        --sidebar-foreground: 240 5.3% 26.1%;
        --sidebar-primary: 240 5.9% 10%;
        --sidebar-primary-foreground: 0 0% 98%;
        --sidebar-accent: 240 4.8% 95.9%;
        --sidebar-accent-foreground: 240 5.9% 10%;
        --sidebar-border: 220 13% 91%;
        --sidebar-ring: 217.2 91.2% 59.8%;
    }

    .dark {
        --background: 0 0% 3.9%;
        --foreground: 0 0% 98%;
        --card: 0 0% 3.9%;
        --card-foreground: 0 0% 98%;
        --popover: 0 0% 3.9%;
        --popover-foreground: 0 0% 98%;
        --primary: 177 100% 28%;
        --primary-light: #008f8829;
        --primary-foreground: 0 0% 9%;
        --secondary: 0 0% 14.9%;
        --secondary-foreground: 0 0% 98%;
        --muted: 0 0% 14.9%;
        --muted-foreground: 0 0% 63.9%;
        --accent: 0 0% 14.9%;
        --accent-foreground: 0 0% 98%;
        --destructive: 0 62.8% 30.6%;
        --destructive-foreground: 0 0% 98%;
        --border: 0 0% 14.9%;
        --input: 0 0% 14.9%;
        --ring: 0 0% 83.1%;

        --chart-1: 220 70% 50%;
        --chart-2: 160 60% 45%;
        --chart-3: 30 80% 55%;
        --chart-4: 280 65% 60%;
        --chart-5: 340 75% 55%;
        --success: 123 46% 34%;
        --rating: 43 100% 50%;
        --sidebar-background: 240 5.9% 10%;
        --sidebar-foreground: 240 4.8% 95.9%;
        --sidebar-primary: 224.3 76.3% 48%;
        --sidebar-primary-foreground: 0 0% 100%;
        --sidebar-accent: 240 3.7% 15.9%;
        --sidebar-accent-foreground: 240 4.8% 95.9%;
        --sidebar-border: 240 3.7% 15.9%;
        --sidebar-ring: 217.2 91.2% 59.8%;
    }
}

your issue stems from relying on native styling which is still in JS.

What exactly do you mean by that? I use style={...} only in very few cases, where nativewind is limited, but for stuff like flex-row, I always use the className.
Here's the code for the HotelList you showed in your screen recording:

export function HotelListClient({
    block,
    hotels,
}: {
    block: HotelList;
    hotels: Record<string, HotelSmall>;
}) {
    return (
        <View className="flex-row flex-wrap items-stretch">
            {block.hotels.map((hotel, idx) => (
                <HotelWidget key={idx} block={hotel} hotel={hotels[hotel.hotelId]!} />
            ))}
        </View>
    );
}

@redkean
Copy link

redkean commented Oct 9, 2025

export function HotelListClient({
    block,
    hotels,
}: {
    block: HotelList;
    hotels: Record<string, HotelSmall>;
}) {
    return (
        <View className="flex flex-row flex-wrap items-stretch">
            {block.hotels.map((hotel, idx) => (
                <HotelWidget key={idx} block={hotel} hotel={hotels[hotel.hotelId]!} />
            ))}
        </View>
    );
}

you should add flex in your className, react native has default styling which is blocked when the site is not fully loaded.
in your case, flex-row flex-wrap items-stretch doesn't do anything because web browser's default display is block.

@Tobi696
Copy link
Author

Tobi696 commented Oct 9, 2025

That might be it. Means in all other places where I took "flex flex-col" for the default, I have to add that explicitly. Will add it and post an update.

@Tobi696
Copy link
Author

Tobi696 commented Oct 9, 2025

@redkean Crazy catch, wouldn't expect the fix to be that easy...
I just added to my global.css

div {
    display: flex;
    flex-direction: column;
}

And now cls is already down to 0.02.
I will add that to the default global.css in the PR as well.
@redkean Do you have revolut or some "Buy me a coffee" link?

@redkean
Copy link

redkean commented Oct 9, 2025

@redkean Crazy catch, wouldn't expect the fix to be that easy... I just added to my global.css

div {
    display: flex;
    flex-direction: column;
}

And now cls is already down to 0.02. I will add that to the default global.css in the PR as well. @redkean Do you have revolut or some "Buy me a coffee" link?

you don't have to, i'm glad i can help. but if you insist then it's in my profile 😅

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.

3 participants