Next.js Discord

Discord Forum

Working with external API

Answered
Bighead carp posted this in #help-forum
Open in Discord
Bighead carpOP
I have an authorization context. I set up it all and everything seemed okey. But I was getting an error like this;
https://cdn.ramco.mbps.tk/cdn/yiyldian3.png
How can I fix this?
Answered by joulev
if you need dynamic meta tags based on states, just use them directly, they will be automatically moved to head for you
"use client";

import { useState } from "react";

import Input from "~/components/forms/input";

export default function Page() {
  const [content, setContent] = useState("Test dynamic meta tags");
  return (
    <div>
      <meta name="description" content={content} />
      <Input type="text" value={content} onChange={e => setContent(e.target.value)} />
    </div>
  );
}


NOTE afaik this is not documented, it could break at any time, but for now it is working well. Do add a test in your code to ensure you know when it ever stops working
View full answer

42 Replies

Bighead carpOP
"use client";
import React, { createContext, useContext, useState, useEffect } from "react";

const AuthContext = createContext<any>(null);

export const AuthContextProvider = ({ children }: { children: any }) => {
  const [loggedIn, setLoggedIn] = useState(false);
  function getLoggedIn() {
    fetch(`${process.env.NEXT_PUBLIC_API_URL}/api/auth/signedIn`, {
      credentials: "include",
    })
      .then((response) => response.json())
      .then((json) => {
        setLoggedIn(json);
      })
      .catch((err) => setLoggedIn(false));
  }
  useEffect(() => {
    getLoggedIn();
  }, []);
  const value = { getLoggedIn: getLoggedIn, loggedIn: loggedIn };
  return <AuthContext.Provider value={value}>{children}</AuthContext.Provider>;
};

export const useAuthContext = () => useContext(AuthContext);
@joulev i fixed one of them, another error is that; https://cdn.ramco.mbps.tk/cdn/5kbkhca10s.png
and give me the code of that part
Bighead carpOP
this is home;
//app/page.tsx
"use client";
import Image from "next/image";
import Layout from "./layout";

export default function Home() {
  return (
    <Layout>
      <div className="text-white">home</div>
    </Layout>
  );
}


this is navbar;
//app/Components/Navbar.tsx
"use client";

import { useAuthContext } from "../Context/store";

export default function Navbar() {
  const { loggedIn } = useAuthContext();
  return (
      <div>{loggedIn?.email}</div>
  );
}


and this is layout.tsx
//app/layout.tsx
import React from "react";
import Navbar from "./Components/Navbar";
import { AuthContextProvider } from "./Context/store";
import "./globals.css";
import { Inter } from "next/font/google";

const Layout = ({
  children,
  metaTags,
}: {
  children: React.ReactNode;
  metaTags?: any | [];
}) => {
  return (
    <>
      <AuthContextProvider>
        <html>
          <head>
            {metaTags?.map((meta: any, index: any) => (
              <>
                <meta
                  key={index}
                  property={meta.property}
                  content={meta.content}
                />
              </>
            ))}
          </head>

          <body>
            <Navbar />
            {children}
          </body>
        </html>
      </AuthContextProvider>
    </>
  );
};

export default Layout;
so just use
//app/page.tsx
"use client";
import Image from "next/image";

export default function Home() {
  return (
    <div className="text-white">home</div>
  );
}
with your code it would be rendered like
<Layout>
  <Layout>
    <div className="text-white">home</div>
  </Layout>
</Layout>

and the double <html> etc can cause all sorts of problems
next.js already handles <Layout /> for you
so dont use it inside page files as well
Bighead carpOP
well , if i want use the meta tags , can i add again?
Bighead carpOP
@joulev ?
Bighead carpOP
how?
Bighead carpOP
why do i need this?
@Bighead carp why do i need this?
in order to use the meta tags?
Bighead carpOP
but why do i have to apply this for every page?
if you need dynamic meta tags based on states, just use them directly, they will be automatically moved to head for you
"use client";

import { useState } from "react";

import Input from "~/components/forms/input";

export default function Page() {
  const [content, setContent] = useState("Test dynamic meta tags");
  return (
    <div>
      <meta name="description" content={content} />
      <Input type="text" value={content} onChange={e => setContent(e.target.value)} />
    </div>
  );
}


NOTE afaik this is not documented, it could break at any time, but for now it is working well. Do add a test in your code to ensure you know when it ever stops working
Answer
Bighead carpOP
yes
its working
thanks to @joulev & @alfon
should i close?
or other users get info for auth context :)
Original message was deleted
if you want to close then follow these instructions
Bighead carpOP
ohh
wait
@Bighead carp how can i block access to /dashboard if loggedIn is false?
since you are using client-side rendering i'd use usePathname, then listen to isLoggedIn inside a useEffect and redirect when necessary

something like this
const router = useRouter();
const pathname = usePathname();
useEffect(() => {
  if (pathname === "/dashboard" && !isLoggedIn)
    router.push("/login");
}, [router, pathname, isLoggedIn]);
Bighead carpOP
what is that?
@Bighead carp what is that?
this is caused by a browser extension
@Bighead carp i think i dont need pathname
then how do you know if you are in /dashboard from that AuthContextProvider?
@Bighead carp i'm using app router
Bighead carpOP
if you have a way of detecting auth state from server components, then simply use this in /dashboard
const isLoggedIn = await getAuthState();
if (!isLoggedIn) redirect("/login");
return ...

but from your code idt you have this system yet, and all things auth-related are put inside that auth provider, then you need usePathname or a similar hook to know that you are in /dashboard
Bighead carpOP
thank you ❣️
oh uh