App Router - How to wrap a layout in session to require login?

I want to force all users to be logged in to access a section of the site using a certain layout. For testing purposes I want the top level layout in the app directory to check for an existing session and redirect to sign in if no session exists. The next auth docs seem to be for the pages directory and those methods didn't seem to work. Is there a guide to do this with the app directory that I missed on the next auth pages? I've read that middleware might be the way to go here, with match on the routes where it is to apply. Is there an example of database session middleware to achieve this? If not, how can I modify the start template layout (below) to check for session server side?
import "~/styles/globals.css";
import { Inter } from "next/font/google";
import { TRPCReactProvider } from "~/trpc/react";

const inter = Inter({
subsets: ["latin"],
variable: "--font-sans",
});

export const metadata = {
title: "Test",
description:
"Test Site",
icons: [{ rel: "icon", url: "/favicon.ico" }],
};

export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<html lang="en">
<body className={`font-sans ${inter.variable}`}>
<TRPCReactProvider>{children}</TRPCReactProvider>
</body>
</html>
);
}
import "~/styles/globals.css";
import { Inter } from "next/font/google";
import { TRPCReactProvider } from "~/trpc/react";

const inter = Inter({
subsets: ["latin"],
variable: "--font-sans",
});

export const metadata = {
title: "Test",
description:
"Test Site",
icons: [{ rel: "icon", url: "/favicon.ico" }],
};

export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<html lang="en">
<body className={`font-sans ${inter.variable}`}>
<TRPCReactProvider>{children}</TRPCReactProvider>
</body>
</html>
);
}
Solution:
I ended up using the following approach, it works well enough it seems: ``` // added the following import import { getServerAuthSession } from "~/server/auth"; ...
Jump to solution
1 Reply
Solution
WeiKaiLe
WeiKaiLe9mo ago
I ended up using the following approach, it works well enough it seems:
// added the following import
import { getServerAuthSession } from "~/server/auth";

export default async function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
const session = await getServerAuthSession();

// Check for session user and redirect if not found.
if (!session?.user) {
redirect("/api/auth/signin");
}
return (
<html lang="en">
<body className={`font-sans ${inter.variable}`}>
<TRPCReactProvider>{children}</TRPCReactProvider>
</body>
</html>
);
}
// added the following import
import { getServerAuthSession } from "~/server/auth";

export default async function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
const session = await getServerAuthSession();

// Check for session user and redirect if not found.
if (!session?.user) {
redirect("/api/auth/signin");
}
return (
<html lang="en">
<body className={`font-sans ${inter.variable}`}>
<TRPCReactProvider>{children}</TRPCReactProvider>
</body>
</html>
);
}
Want results from more Discord servers?
Add your server