Reputation: 1886
I was trying to use #{id}
to move user to an element with the given id, but the href somehow always get its hashtag converted into %23. Is there a way to prevent this?
UPDATE: This is one of the components that have that issue. When the item.href
contains "#", it would become %23
on rendering. It was used in a drop down menu component.
export interface NavItemType {
id: string;
name: string;
href: string | "#" | "/#";
toId?: string;
targetBlank?: boolean;
children?: NavItemType[];
megaMenu?: MegamenuItem[];
type?: "dropdown" | "megaMenu" | "none";
}
const renderDropdownMenuNavlink = (item: NavItemType) => {
return (
<Link
href={{
pathname: item.href || undefined,
}}
passHref
>
<a
target={item.targetBlank ? "_blank" : undefined}
rel="noopener noreferrer"
className={
"flex items-center font-normal text-neutral-6000 dark:text-neutral-400 py-2 px-4 rounded-md hover:text-neutral-700 hover:bg-neutral-100 dark:hover:bg-neutral-800 dark:hover:text-neutral-200" +
(router.pathname === item.href ? "!font-medium !text-neutral-900 dark:!text-neutral-100" : "")
}
>
{item.name}
{item.type && (
<ChevronDownIcon
className="ml-2 h-4 w-4 text-neutral-500"
aria-hidden="true"
/>
)}
</a>
</Link>
);
};
Upvotes: 4
Views: 2005
Reputation: 1
As @Marlom said, your url is encoded when using #, resulting with a %23 in your url. My solution is to use the hash property of the next/link component. Maybe parsing it before if your href contains the #? My solution would be :
<Link href={{ pathname: props.href, hash: props.hash }}>
</Link>
With your example (and the parsing) :
const renderDropdownMenuNavlink = (item: NavItemType) => {
const [pathname, hash] = item.href.split("#");
return (
<Link
href={{
pathname: pathname || undefined,
hash: hash,
}}
>
<a
target={item.targetBlank ? "_blank" : undefined}
rel="noopener noreferrer"
className={
"flex items-center font-normal text-neutral-6000 dark:text-neutral-400 py-2 px-4 rounded-md hover:text-neutral-700 hover:bg-neutral-100 dark:hover:bg-neutral-800 dark:hover:text-neutral-200" +
(router.pathname === item.href ? "!font-medium !text-neutral-900 dark:!text-neutral-100" : "")
}
>
{item.name}
{item.type && (
<ChevronDownIcon
className="ml-2 h-4 w-4 text-neutral-500"
aria-hidden="true"
/>
)}
</a>
</Link>
);
};
Or, if it is possible, adding a hash property to your NavItemType interface so you don't have to parse it :
export interface NavItemType {
id: string;
name: string;
href: string;
hash: string;
toId?: string;
targetBlank?: boolean;
children?: NavItemType[];
megaMenu?: MegamenuItem[];
type?: "dropdown" | "megaMenu" | "none";
}
Upvotes: 0
Reputation: 688
NextJS uses the native UrlObject
from node
or browser
if not SSR.
pahname
is specifically used for path name so anything not accepted there will be encoded, what you might need is hash
but you might also be able to use your item.href
directly into href
prop of your Link
Upvotes: 4