preact-router icon indicating copy to clipboard operation
preact-router copied to clipboard

activeClassName won't work if Link's href has a search

Open zaaack opened this issue 7 years ago • 7 comments

e.g.

<Link activeClassName="active" href={`/type/book?q=${query.q || ''}`}>Book</Link>

zaaack avatar May 23 '17 05:05 zaaack

Ah good call. What would the most predictable behavior be here? Also I think there's an option to specify the match URL manually:

<Link
  activeClassName="active"
  path="/type/book"
  href={`/type/book?q=${query.q || ''}`}
>
  Book
</Link>

(not sure if that helps)

developit avatar Jun 03 '17 19:06 developit

@developit I find out the path property later and am using it now. I expect Link should be activated when href's path is matching current path, not the whole href with search when comparing to only the path of current url in default behavior.

zaaack avatar Jun 03 '17 23:06 zaaack

activeClassName also doesn't work if the URL has a hash in it either:

/page-name <-- Works /page-name#contact <-- Doesn't work

OngeUK avatar Sep 13 '17 16:09 OngeUK

Just noticed same thing as @OngeUK Doesn't work with hash.

GuskiS avatar Oct 17 '17 21:10 GuskiS

Also this happens when you have optional params /page/:sub? doesn't match /page

pmkroeker avatar Mar 19 '19 20:03 pmkroeker

Is there any workaround for this?

madhavarshney avatar Sep 08 '20 02:09 madhavarshney

This probably isn't a good way of doing it but I ended up copying the Link component from preact-router/match rewriting it as an ExtendedLink and checking whether the current path begins with the href of the link. (You can probably modify it to allow it to check for path or href prop but this suited me as a quick solution !)

Might be helpful for someone !

export const ExtendedLink: FunctionComponent<LinkProps> = ({ class: c, className, activeClassName, ...props }) => {
  const inactive = [c, className].filter(Boolean).join(' ');
  const active = [c, className, activeClassName].filter(Boolean).join(' ');
  return (
    <Match path={props.href}>
      { ({ path }: { path: string }) => {
        return (
          <Link {...props} class={path.startsWith(props.href!) ? active : inactive} />
        )
      }}
    </Match>
  );
}

mikerhyssmith avatar May 04 '21 19:05 mikerhyssmith