Next.js Discord

Discord Forum

Is making a NextJS component "use-client" bad for SEO?

Answered
West African Lion posted this in #help-forum
Open in Discord
West African LionOP
I want to add a feature to my website's navbar so it can be transparent when loading-in, but once you start scrolling down, it'll become opaque but I'm not sure if this will cause issues with SEO and crawlers.

Website: https://space-precision-systems.netlify.app/

I'm using Framer Motion for the animations, and anything that uses the ScrollY is required to be a client component, so any feedback on a better solution if needed would be appreciated!
Answered by joulev
Since you need access to the scroll position, that requires client side js so you must use client components.

I would not use framer motion here since it’s relatively heavy. Just manually track the scroll position in a react state, then render the opacity based on that state
View full answer

28 Replies

West African LionOP
Oh great! So I don't need to worry about any work-arounds or such?
@joulev Client components are prerendered on the server so it should be totally fine for SEO
West African LionOP
Would there be a better option here, or is making it a client component ok?
@West African Lion Would there be a better option here, or is making it a client component ok?
Since you need access to the scroll position, that requires client side js so you must use client components.

I would not use framer motion here since it’s relatively heavy. Just manually track the scroll position in a react state, then render the opacity based on that state
Answer
But as far as SEO is concerned, your approach is good
but I see what you mean, thanks!
West African LionOP
How would you go about it without Framer? Would I need to use JS to add an event listener for the scroll and then map that to a percentage or something of the opacity?
West African LionOP
And that would need to be in a useEffect or custom hook to stay in sync with the server right?
@West African Lion And that would need to be in a useEffect or custom hook to stay in sync with the server right?
The event listener is declared in useEffect yes, then you update the state (declared with useState) in the event listener
West African LionOP
Thanks!
and not to forget the useEffect dependancy
Thanks you so so much @joulev
You’re welcome
@joulev You’re welcome
West African LionOP
Sorry to bug you again!
Just wanted to know if at a glance, you know why this isn't working
    <motion.nav
      initial={{ backgroundColor: "transparent" }}
      className="fixed top-0 w-screen z-10"
      style={{ backgroundColor: `rgba(0, 0, 0, ${scrollY.get()})` }}
    >
For some reason I'm unable to find great examples of this effect 😦
@American I don't think that Navbar is important for seo, you can make your navbar as client component and other page as server
West African LionOP
Thanks ❤️ So I made it client but the issue I'm running into is getting the background to change on scroll 😦
<motion.nav
      initial={{ backgroundColor: "transparent" }}
      className="fixed top-0 w-screen z-10"
      style={{ backgroundColor: `rgba(0, 0, 0, ${scrollY.get()})` }}
    >

This doesn't seem to work for some reason and I'm not sure what I'm doing wrong 😦
@American you have to use useScroll or useAnimate and use in motion.div
West African LionOP
In the docs, it says I should use useScroll() but I don't know what I'm doing wrong and I've been at this for days now
  let { scrollYProgress } = useScroll();
  return (
    <motion.nav
      className="fixed top-0 w-screen z-10"
      style={{
        backgroundColor:
          scrollYProgress.getVelocity() > 0 ? "white" : "transparent",
      }}
    >

At this point I'll pay someone to help with this. My health hasn't been great and I just need to get this done. I need the background to change when they scroll down... that's it 😦
@American how much?
West African LionOP
I got it working like this in the end:
  let { scrollY } = useScroll();
  const [navBackgroundColor, setNavBackgroundColor] = useState("transparent");
  const [navBackgroundOpacity, setNavBackgroundOpacity] = useState(1);

  useMotionValueEvent(scrollY, "change", () => {
    setNavBackgroundColor(scrollY.get() > 0 ? "#1d212c" : "transparent");
    setNavBackgroundOpacity(scrollY.getVelocity() > 0 ? 0 : 1);
  });

  return (
    <motion.nav
      className="fixed top-0 w-screen z-10 duration-300 transition-all ease-in-out"
      style={{
        backgroundColor: navBackgroundColor,
        opacity: navBackgroundOpacity,
      }}
    >
    ...
    </motion.div>