Add supabase to mantine based project
Answered
finesse posted this in #help-forum
finesseOP
note: I am new to webdev
I am building a web app with next js, mantine, and supabase
I built out the UI using react/mantine and am now looking to start adding in my database. What is the best way to go about this since mantine uses use client directive? I read on the next js fetching data docs that this might be the best way to do it. https://nextjs.org/docs/app/getting-started/fetching-data#client-components
Is this correct? I want to use the supabase.js library in the server component, wrap my mantine client components in the servercomponent with a suspense and continue as normal. Are there any concerns I should consider?
I am building a web app with next js, mantine, and supabase
I built out the UI using react/mantine and am now looking to start adding in my database. What is the best way to go about this since mantine uses use client directive? I read on the next js fetching data docs that this might be the best way to do it. https://nextjs.org/docs/app/getting-started/fetching-data#client-components
Is this correct? I want to use the supabase.js library in the server component, wrap my mantine client components in the servercomponent with a suspense and continue as normal. Are there any concerns I should consider?
Answered by Greater Shearwater
Yeah, "use client" marks a boundary. So all the components rendered by the component that is marked with "use client" will be client components.
I haven't used Mantine, but I looked up what the AppShell component is, and yeah it seems like it needs to be rendered high up.
But that doesn't mean you need to use
You can create a component and put the the code needed for
You can then import and render this shell component in the
I haven't used Mantine, but I looked up what the AppShell component is, and yeah it seems like it needs to be rendered high up.
But that doesn't mean you need to use
use client at the very top. For example, you can still keep your layout.tsx and page.tsx server components.You can create a component and put the the code needed for
AppShell inside it and mark that component with "use client". Allow that component to accept children.You can then import and render this shell component in the
layout.tsx file, wrapping the children. This way you don't have to mark the layout.tsx with use client. And all the children component you are going to render will still be server components.// layout.tsx
export default function RootLayout({ children }: { children: any }) {
return (
<html lang="en" {...mantineHtmlProps}>
<head>
<ColorSchemeScript />
</head>
<body>
<MantineProvider theme={theme}>
<Shell>{children}</Shell> // Wrap your children with the Shell. Children can still be server components
</MantineProvider>
</body>
</html>
);
}
// Shell.tsx
'use client';
import { type ReactNode } from 'react';
import { AppShell, Burger } from '@mantine/core';
import { useDisclosure } from '@mantine/hooks';
export function Shell({ children }: { children: ReactNode }) {
const [opened, { toggle }] = useDisclosure();
return (
<AppShell>
<AppShell.Header>
<Burger />
<div>Logo</div>
</AppShell.Header>
<AppShell.Navbar>Navbar</AppShell.Navbar>
<AppShell.Main>{children}</AppShell.Main>
</AppShell>
);
}8 Replies
Greater Shearwater
Yeah, that should be fine.
I guess you can also just fetch and await the data in the server component, and then pass the data to your client components as well? That's what I usually do. Is there any reason not to do that with your setup?
But yeah using the
I guess you can also just fetch and await the data in the server component, and then pass the data to your client components as well? That's what I usually do. Is there any reason not to do that with your setup?
But yeah using the
use hook and resolving the promise in the client components is fine too.@Greater Shearwater Yeah, that should be fine.
I guess you can also just fetch and await the data in the server component, and then pass the data to your client components as well? That's what I usually do. Is there any reason not to do that with your setup?
But yeah using the `use` hook and resolving the promise in the client components is fine too.
finesseOP
One of the reasons I am concerned is with mantine, it requires use client for hooks, compound components, and callbacks. I am using the "app shell" component by mantine which includes compound components for the header, making me use use client at the top level. If I am correct use client propagates down so then all my files will be SSR and client rendered which I would assume makes me need to concern myself with client side fetching. Does this make sense?
@finesse One of the reasons I am concerned is with mantine, it requires use client for hooks, compound components, and callbacks. I am using the "app shell" component by mantine which includes compound components for the header, making me use use client at the top level. If I am correct use client propagates down so then all my files will be SSR and client rendered which I would assume makes me need to concern myself with client side fetching. Does this make sense?
Greater Shearwater
Yeah, "use client" marks a boundary. So all the components rendered by the component that is marked with "use client" will be client components.
I haven't used Mantine, but I looked up what the AppShell component is, and yeah it seems like it needs to be rendered high up.
But that doesn't mean you need to use
You can create a component and put the the code needed for
You can then import and render this shell component in the
I haven't used Mantine, but I looked up what the AppShell component is, and yeah it seems like it needs to be rendered high up.
But that doesn't mean you need to use
use client at the very top. For example, you can still keep your layout.tsx and page.tsx server components.You can create a component and put the the code needed for
AppShell inside it and mark that component with "use client". Allow that component to accept children.You can then import and render this shell component in the
layout.tsx file, wrapping the children. This way you don't have to mark the layout.tsx with use client. And all the children component you are going to render will still be server components.// layout.tsx
export default function RootLayout({ children }: { children: any }) {
return (
<html lang="en" {...mantineHtmlProps}>
<head>
<ColorSchemeScript />
</head>
<body>
<MantineProvider theme={theme}>
<Shell>{children}</Shell> // Wrap your children with the Shell. Children can still be server components
</MantineProvider>
</body>
</html>
);
}
// Shell.tsx
'use client';
import { type ReactNode } from 'react';
import { AppShell, Burger } from '@mantine/core';
import { useDisclosure } from '@mantine/hooks';
export function Shell({ children }: { children: ReactNode }) {
const [opened, { toggle }] = useDisclosure();
return (
<AppShell>
<AppShell.Header>
<Burger />
<div>Logo</div>
</AppShell.Header>
<AppShell.Navbar>Navbar</AppShell.Navbar>
<AppShell.Main>{children}</AppShell.Main>
</AppShell>
);
}Answer
finesseOP
Ok awesome this is actually how I had it set up currently. I thought when you had
{children} the use client would also propagate downwards, but it seems that isnt the case. Will that work similarly with the <MantineProvider> component since I have the children inside of the <Shell>?And now since my code is build this way, I should be able to use any pattern server side to fetch aslong as I dont need client, and if I do I can use the original fall back I proposed of using the use hook, or what you said making a "parent" component thats server side, do my fetch, then pass it down as props?
Greater Shearwater
{children} doesn’t become client components because you are not actually calling them inside the Shell which is a client component. You are just passing them through. This is a very common pattern.And yeah your
<MantinePtovider> should work without any issues as well.Also yeah you can use those patterns for fetching data. Currently the
page.tsx components you will be rendering inside that route will be server components. So you can do any data fetching there and pass down either the data or the promise to the Mantine client components you will be rendering inside that page component.finesseOP
Got it thank you I learned a lot! Have a happy holiday!
Greater Shearwater
Happy holidays for you as well!