Next.js Discord

Discord Forum

You're importing a component that needs next/headers

Answered
Blue Picardy Spaniel posted this in #help-forum
Open in Discord
Blue Picardy SpanielOP
# lib/auth.ts:
import type { Session, User } from "lucia";
import { Discord } from "arctic";
import { Lucia } from "lucia";
import { PrismaAdapter } from "@lucia-auth/adapter-prisma";
import { cache } from "react";
import { client } from "@/lib/db";
import { cookies } from "next/headers";
import { env } from "@/env";

const adapter = new PrismaAdapter(client.session, client.user);

export const lucia = new Lucia(adapter, {
  sessionCookie: {
    expires: false,
    attributes: {
      secure: process.env.NODE_ENV === "production" // eslint-disable-line no-process-env
    },
    getUserAttributes: attributes => {
      console.log(attributes);

      return {
        id: attributes.id
      };
    }
  }
});

export const discord = new Discord(
  env.DISCORD_CLIENT_ID,
  env.DISCORD_CLIENT_SECRET,
  "http://localhost:3000/login/callback"
);

export const validateRequest = cache(
  async (): Promise<{ user: User; session: Session } | { user: null; session: null }> => {
    const sessionId = cookies().get(lucia.sessionCookieName)?.value ?? null;
    if (!sessionId) {
      return {
        user: null,
        session: null
      };
    }

    const result = await lucia.validateSession(sessionId);

    try {
      if (result.session && result.session.fresh) {
        const sessionCookie = lucia.createSessionCookie(result.session.id);
        cookies().set(sessionCookie.name, sessionCookie.value, sessionCookie.attributes);
      }
      if (!result.session) {
        const sessionCookie = lucia.createBlankSessionCookie();
        cookies().set(sessionCookie.name, sessionCookie.value, sessionCookie.attributes);
      }
    } catch {}

    return result;
  }
);

declare module "lucia" {
    interface Register {
        Lucia: typeof lucia;
        DatabaseUserAttributes: DatabaseUserAttributes;
    }
}

interface DatabaseUserAttributes {
    id: string;
}

You're importing a component that needs next/headers. That only works in a Server Component which is not supported in the pages/ directory

I'm using the app directory though.
Answered by Ray
this error usually cause by
1, trying to use next/headers in client component
2, barrel file
View full answer

21 Replies

American Crow
@Blue Picardy Spaniel didn't fix it
make sure you are not using validateRequest, discord and lucia in client component
@Blue Picardy Spaniel im not
are you using barrel file
@Ray are you using barrel file
Blue Picardy SpanielOP
how do i know if im using that
do you import and export thing in index.ts
@Ray do you import and export thing in index.ts
Blue Picardy SpanielOP
in my auth.ts?
this error usually cause by
1, trying to use next/headers in client component
2, barrel file
Answer
Blue Picardy SpanielOP
this is all i import in my auth.ts:

import type { Session, User } from "lucia";
import { Discord } from "arctic";
import { Lucia } from "lucia";
import { PrismaAdapter } from "@lucia-auth/adapter-prisma";
import { cache } from "react";
import { client } from "@/lib/db";
import { cookies } from "next/headers";
import { env } from "@/env";
and i export lucia and discord
Blue Picardy SpanielOP
components/navbar/profile.ts:
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"
import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuTrigger } from "@/components/ui/dropdown-menu"
import { Button } from "@/components/ui/button"
import { LogOut } from "lucide-react"
import { Skeleton } from "@/components/ui/skeleton"
import { validateRequest } from "@/lib/auth";

export default async function Profile() {
  const { user } = await validateRequest(); // <--

  return (
    <h1>{user?.id || "n/a"}</h1>
  );
}

lib/auth.ts:
export const lucia = new Lucia(adapter, { // <--
  sessionCookie: {
    expires: false,
    attributes: {
      secure: process.env.NODE_ENV === "production" // eslint-disable-line no-process-env
    },
    getUserAttributes: attributes => {
      console.log(attributes);

      return {
        id: attributes.id
      };
    }
  }
});

export const discord = new Discord( // <--
  env.DISCORD_CLIENT_ID,
  env.DISCORD_CLIENT_SECRET,
  "http://localhost:3000/login/callback"
);
@Ray ok where do you render `<Profile />`?
Blue Picardy SpanielOP
in a client component
@Blue Picardy Spaniel in a client component
that's the problem
@Ray this error usually cause by 1, trying to use next/headers in client component 2, barrel file
American Crow
one more question regarding this. maybe you know so i dont have to test it.
By using the server only package, in this case for the auth.ts would that result in a better error message maybe even pointing to the <Profile> Component?
@Ray yeah
American Crow
okay thanks i was going to suggest that reading this question initally but wasn't sure. So i might do suggest it in the future for debugging tasks like this