How can I pass the promise as a provider to Nextjs14 in Layout

How to Handle Promises in a Provider Component in Next.js 14 Layout?

I’m trying to use LucidProvider in my Next.js 14 layout to wrap all my components. Inside the provider, I initialize Lucid and update the state. However, Lucid returns a promise, which is causing the following error:

Error: Element type is invalid. Received a promise that resolves to: undefined. Lazy element type must resolve to a class or function.

Here’s the initialization logic in LucidProvider.tsx:

const blockfrost = new Blockfrost(BF_URL, BF_PID);
Lucid(blockfrost, NETWORK).then(setLucid).catch((error) => console.log(error));

When I comment out these lines, the error disappears. I’ve tried different approaches, including using default and named imports, as well as dynamic, but none of them resolved the issue. How can I properly pass the resolved promise as a provider in the Next.js 14 layout?

LucidProvider.tsx


'use client';

import React, { createContext, useContext, useEffect, useState } from "react";
import { Blockfrost, Lucid, LucidEvolution, Network } from "@lucid-evolution/lucid";

interface LucidContextType {
  lucid: LucidEvolution | undefined;
}

const LucidContext = createContext<LucidContextType | undefined>(undefined);

const BF_URL = process.env.NEXT_PUBLIC_BF_URL!;
const BF_PID = process.env.NEXT_PUBLIC_BF_PID!;
const NETWORK = process.env.NEXT_PUBLIC_CARDANO_NETWORK as Network;

export interface ProvidersProps {
  children: React.ReactNode;
}
export default function LucidProvider({ children }: ProvidersProps) {
  const [lucid, setLucid] = useState<LucidEvolution>();

  useEffect(() => {
    const blockfrost = new Blockfrost(BF_URL, BF_PID);
    Lucid(blockfrost, NETWORK).then(setLucid).catch((error) => console.log(error));
  }, []);

  return (
    <LucidContext.Provider value={{ lucid, }}>
      {children}
    </LucidContext.Provider>
  );
};

export const useLucid = () => {
  const context = useContext(LucidContext);
  if (!context) throw new Error("useLucid must be used within a LucidProvider");
  return context;
};

Layout.tsx

import dynamic from "next/dynamic";
// const LucidProvider = dynamic(() => import('./LucidProvider'))
import LucidProvider from "./LucidProvider";
..
..
..
..
..
export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html suppressHydrationWarning lang="en">
      <head />
      <body className={clsx(
        "min-h-screen bg-background font-sans antialiased",
        fontSans.variable,
        fontComfortaa.variable
      )}>
        <LucidProvider>
        <Navbar />
          <Providers themeProps={{ attribute: "class", defaultTheme: "dark" }}>
            <div className="relative flex flex-col h-screen">
              <main className="container mx-auto  flex-grow">{children}</main>
            </div>
          </Providers>
        </LucidProvider>
      </body>
    </html>
  );
}