Next.js Discord

Discord Forum

Server Components with session data

Unanswered
yolocat posted this in #help-forum
Open in Discord
Hi y'all,
migrating my project from Next.js 14 to 15, and while doing so I thought I'd refactor some parts that I'd have to change anyways.

The setPath call in layout.tsx doesn't look idiomatic, but I'm wondering how to do this better and cleaner without having to pass teamID down the component tree

// app/[team]/layout.tsx
import { setPath, getTeam } from "@/lib/cache";

export default async function Layout({
    children,
    params,
}: {
    children: React.ReactNode;
    params: Promise<{ team: string; }>;
}) {
    const { team: teamID } = await params;
    setPath(teamID);

    return (
        <SomeComponent />
    );
}

async function SomeComponent() {
    const team = await getTeam();

    return (
        <span>{team.name}</span>
    );
}


// lib/cache.ts
let current = "personal";
export const setPath = (path: string) => {
    current = path;
};

async function getCachedTeam(path: string, personal: UserTeam, others: UserTeam[]) {
    "use cache";

    if(path === "personal") {
        return personal;
    }

    const team = others.find((t) => t.team.path === current);
    if(!team) redirect("/personal");

    return team;
}

export async function getTeam() {
    const account = await getAccount();
    if(!account) return null;

    return getCachedTeam(current, account.personalTeam, account.otherTeams);
}

const getCachedAccount = async(
    ghId: string,
    email: string,
    firstName: string,
    lastName: string | null,
    image: string | null,
) => {
    "use cache";
    cacheLife("hours");
    cacheTag(`account-${ghId}`);

    // makes an sql query with @vercel/postgres
    return await getAccountOrCreate(ghId, email, firstName, lastName, image);
};

export const getAccount = async() => {
    const session = await auth();
    if(!session) return null;

    const { user } = session;
    if(!user) return null;

    return await getCachedAccount(user.gh, user.email, user.firstName, user.lastName, user.image);
};

0 Replies