#Spinner (Page loader)

79 messages · Page 1 of 1 (latest)

dreamy topaz
#

I made this spinner in a file preload.tsx:

"use client";
import { useState, useEffect } from "react";
import { TbLoader2 } from "react-icons/tb";

export default function Preloader() {
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    const Timer = setTimeout(() => {
      setLoading(false);
    }, 2000);

    return () => clearTimeout(Timer);
  }, []);

  return loading ? (
    <div className="h-screen flex items-center justify-center">
      <TbLoader2 className="h-8 w-8 animate-spin" />
    </div>
  ) : null;
}

Then in layout I just display it like this: <Preload />
How can I make it so when the loader is active, other content of the page is all hidden and after 2 seconds loader disappears and initial page's content is visible?

daring 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)

mild cipher
#

you can use css with tailwind to do that

#

write a javascript script that toggles the classes name it for example Loader.ts can remove the classes of your page by adding hidden

#

and after make it wait 2 secends and then remove the hidden

dreamy topaz
mild cipher
#

doing it

#
// loader.ts
import { useState, useEffect } from "react";

export function useLoader(duration = 2000): boolean {
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    const timer = setTimeout(() => {
      setLoading(false);
    }, duration);

    return () => clearTimeout(timer);
  }, [duration]);

  return loading;
}
``` here you go
#

then when i add the visible part

#
// loader.ts
import { useState, useEffect } from "react";

export function useLoader(duration = 2000): boolean {
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    const timer = setTimeout(() => {
      setLoading(false);
    }, duration);

    return () => clearTimeout(timer);
  }, [duration]);

  // Set the visibility of the page to false while loading
  useEffect(() => {
    if (loading) {
      document.body.style.visibility = "hidden";
    } else {
      document.body.style.visibility = "visible";
    }
  }, [loading]);

  return loading;
}
#

here

#

@dreamy topaz

dreamy topaz
#

and where does the spinner part go?

<div className="h-screen flex items-center justify-center">
  <TbLoader2 className="h-8 w-8 animate-spin" />
</div>
mild cipher
#

sorry but i meant that you reqiure this in your loading page and then the loader goes in the page

dreamy topaz
#

So I put loader component in layout.tsx?

mild cipher
#

the loader.ts is required and yes i think

dreamy topaz
#

and finally how do I use useLoader in te layout?

mild cipher
#

i dont know dont know layout.tsx much

dreamy topaz
#

it's like _app.tsx in React

mild cipher
#

i never use _app or layout

dreamy topaz
#

in nextjs?

mild cipher
#

yes im new

dreamy topaz
#

oh damn

#

do you use > v13 or < 13 version?

mild cipher
#

14.2.1

dreamy topaz
#

Okay, we should get back to the topic

mild cipher
#

ok let get back

dreamy topaz
#
// loader.ts
"use client";
import { useState, useEffect } from "react";

export function useLoader(duration = 2000): boolean {
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    const timer = setTimeout(() => {
      setLoading(false);
    }, duration);

    return () => clearTimeout(timer);
  }, [duration]);

  // Set the visibility of the page to false while loading
  useEffect(() => {
    if (loading) {
      document.body.style.visibility = "hidden";
    } else {
      document.body.style.visibility = "visible";
    }
  }, [loading]);

  return loading;
}
#

This is the component I have rn

mild cipher
#

like this ```ts
// layout.tsx
import { useLoader } from "./loader";
import Preloader from "./preload";

export default function Layout() {
const loading = useLoader(); // You can pass duration as an argument if needed

return (
<>
<Preloader /> {/* Render your Preloader component /}
{/
Other content of the page /}
<div style={{ visibility: loading ? "hidden" : "visible" }}>
{/
Your page content goes here */}
</div>
</>
);
}

#

this is ur layout.tsx

#

i now understand

#

💻

dreamy topaz
#
...
          <Spinner />
          <div style={{ visibility: loading ? "hidden" : "visible" }}>
            <Navbar user={user} />
            <div className="mx-auto my-4 flex max-w-7xl flex-1 justify-center items-center">
              {children}
            </div>
          </div>
...
#

I did it like that

#

let me check

mild cipher
#

oh well

dreamy topaz
#

tho we got one problem

mild cipher
#

what

dreamy topaz
#

Error: Attempted to call useLoader() from the server but useLoader is on the client. It's not possible to invoke a client function from the server, it can only be rendered as a Component or passed to props of a Client Component.

mild cipher
#

use "use client"

#

at top

dreamy topaz
#

and I can't set layout.tsx to be client component, because metadata is set there

mild cipher
#

oh

#

then use the spiiner in a client component like page.tsx

dreamy topaz
#

but my navbar is displayed in layout

#

I need everything to be hidden

mild cipher
#

move your nav if you need

dreamy topaz
#

you mean I could do new component ("layout") in page.tsx where I do all the spinner logic?

mild cipher
#

no put everything the header the loader in your page

dreamy topaz
#

but..

mild cipher
#

wj

#

what

dreamy topaz
#

then navbar is not visible in all pages

#

cuz layout is made for that

mild cipher
#

oh

dreamy topaz
#

a part of website that is visible in any page

#

even error 404 page

mild cipher
#

make a div in the layout that conanids the navbar and content

#

i gtg

dreamy topaz
dreamy topaz
#

So I finally managed to solve it by converting layout.tsx to a client component by adding "use client"; and moving metadata to page.tsx (it's not global metadata, so I have to set it for each page manually).

dreamy topaz
#

Still would be interested to know if that's a good practice or not.

wide star
#

but

#

u can do this

#
  1. center the spinner and design it
#
  1. add z-index 99999
#
  1. add opacity to background or solid color so it doesnt see properly
#

just that

dreamy topaz
wide star
#

on body

#

What I actually mean you to do is @dreamy topaz v

#

the first example

#

it seems good to me however ik you are not using material ui, I'm just tellig how should u design it

dreamy topaz
#

Oh