#context from context provider in layout not available in page?

12 messages · Page 1 of 1 (latest)

vestal bramble
#

I am getting error "Error: (0 , components_Context_LangContext_LangContext__WEBPACK_IMPORTED_MODULE_2_.useLangContext) is not a function"

src/app/[lang]/page.tsx:
const {dictionary} = useLangContext();

Is it because both layout and page are server components?

Code below:

white graniteBOT
#

🔎 This post has been indexed in our web forum and will be seen by search engines so other users can find it outside Discord

🕵️ Your user profile is private by default and won't be visible to users outside Discord, if you want to be visible in the web forum you can add the "Public Profile" role in id:customize

✅ You can mark a message as the answer for your post with Right click -> Apps -> Mark Solution
(if you don't see the option, try refreshing Discord with Ctrl + R)

vestal bramble
#
// LangContext.tsx
"use client";

import React, { useContext } from "react";
import { Locale } from "@root/i18n-config";
import { Dictionary } from "@/types/types";

interface ILangContext {
    lang: Locale;
    dictionary: Dictionary;
};

export const LangContext = React.createContext<ILangContext | undefined>(undefined);

interface ILangProvider {
    lang: Locale;
    dictionary: Dictionary;
    children?: React.ReactNode;
};

export const LangProvider: React.FC<ILangProvider> = (props) => {
    return (
        <LangContext.Provider value={{
            lang: props.lang,
            dictionary: props.dictionary,
        }}>{props.children}</LangContext.Provider>
    );
};

export const useLangContext = () => {
    const context = useContext(LangContext);

    if (context === undefined) {
        throw new Error("useLangContext must be used within a LangProvider");
    }

    return context;
};
#
// layout.tsx

import type { Metadata } from "next";
import NextTopLoader from "nextjs-toploader";
import BaseLayout from "@/layouts/BaseLayout/BaseLayout";
import { getDictionary } from "@/get-dictionary";
import { Locale } from "@root/i18n-config";
import { Inter } from "next/font/google";
import "./globals.scss";
import "bootstrap/dist/css/bootstrap.min.css";
import { LangProvider } from "@/components/Context/LangContext/LangContext";

const inter = Inter({ subsets: ["latin"] });

export const metadata: Metadata = {
  title: "Home",
};

export default async function RootLayout({
    params: { lang },
    children,
}: Readonly<{
    params: { lang: Locale };
    children: React.ReactNode;
}>) {
    const dictionary = await getDictionary(lang);

    return (
        <html lang={lang}>
            <body className={inter.className}>
                <LangProvider lang={lang} dictionary={dictionary}>
                    <BaseLayout>
                        {children}
                    </BaseLayout>
                </LangProvider>
            </body>
        </html>
    );
};
#
// src/app/[lang]/page.tsx

import { Locale } from "@root/i18n-config";
import Link from 'next/link';
import { useLangContext } from "@/components/Context/LangContext/LangContext";

export default function IndexPage() {
    const {dictionary} = useLangContext(); // ERROR HERE

    return (
        <div></div>
    );
};
#

the same const {dictionary} = useLangContext(); does work in a client component that is inside <BaseLayout>

#

or does layout not wrap pages?

#

I have no idea why the context is not available in page, but is available in BaseLayout

vestal bramble
#

do I also need to do const dictionary = await getDictionary(lang); in page.tsx instead of using the context?

#

because that works

#

but that kind of defeats the purpose of layout

#

because i am repeating myself twice