xxxbud
xxxbud

Reputation: 113

How to check for active path when using dynamic routes?

If I click in my project element from HeadlessCMS that is /projects/slug-name my Navbar button projects (LinkItem) is not highlighted with bgColor ---> bg={active ? bgColor : undefined}.

What I got to do with this line const active = path === href // || href == "/projects/slug"; so that if I enter /projects/slug-random-name it will detect that I am in /projects path and then set active to be true and then change the color to bgColor?


const LinkItem = ({ href, path, target, children, ...props }) => {
  const active = path === href // || href == "/projects/slug"; what I got to do? if there is a slug in /projects/HERE, I would like to set navlink button Projects to background color bgColor to active
  const inactiveColor = useColorModeValue("gray200", "whiteAlpha.900");
  const bgColor = useColorModeValue("#F7F2F2", "#21262D");
  const textColor = useColorModeValue("gray.900", "gray.100");
 

  return (
    <NextLink href={href} passHref scroll={false}>
      <Link
        p="4px"
        pl={3}
        pr={3}
        rounded="3xl"
        bg={active ? bgColor : undefined} // set background color if path === href
        color={active ? textColor : inactiveColor}
        target={target}
        style={{ textDecoration: "none" }}
        transition="1000ms"
        {...props}
      >
        {children}
      </Link>
    </NextLink>
  );
};
const Navbar = (props) => {
  const borderColor = useColorModeValue("#EDE9E9", "gray.800");
  const backgroundColor = useColorModeValue("#EDE9E9", "#090C10");
  const { path } = props;
  console.log(path);

  return (
    <Box as="nav" {...props} mt="8px">
      <Container maxW="2xl">
        <Flex gap="4" align="center" minWidth="max-content">
          <Box>
            <Heading size="md">
              <IoWaterOutline size={28} color="#07344D" />
            </Heading>
          </Box>
          <Spacer />
          <Box bg={backgroundColor} rounded="3xl">
            <Stack
              direction="row"
              display={{ base: "none", md: "flex" }}
              width={{ base: "full", md: "auto" }}
              alignItems="center"
              //   mt={{ base: 4, md: 0 }}
              border="2px"
              borderColor={borderColor}
              rounded="3xl"
              p={1}
            >
              <LinkItem href="/" path={path}>
                Strona główna
              </LinkItem>
              <LinkItem href="/about" path={path}>
                O firmie
              </LinkItem>
              <LinkItem href="/projects" path={path}>
                Realizacje
              </LinkItem>
              <LinkItem href="/contact" path={path}>
                Kontakt
              </LinkItem>
            </Stack>
          </Box>
        </Flex>
      </Box>
</Container>

It only changes background color to bgColor if I press LinkItem component with path={path}.

<LinkItem href="/contact" path={path}>
 Kontakt
</LinkItem>

I console logged a slug elements and whenever I enter it, it gives me path e.g.: /projects/test-2 but the LinkItem component in Navbar is not highlighted with bgColor (doesn't change the color to be active in projects path, but it is in /projects/test-2 which is `/projects/).

Upvotes: 1

Views: 943

Answers (1)

juliomalves
juliomalves

Reputation: 50288

You can try matching the exact string first, and if that fails (for dynamic routes) check that the path begins with the href string.

const active = path === href || (href.length > 1 && path.startsWith(href));

In the second part of the condition, we check href.length > 1 first to filter out the scenario where href is /, which would match any given path.

Upvotes: 2

Related Questions