Last active
January 17, 2024 07:25
-
-
Save Phryxia/677bb0f4aeb14418e847d6946ba390ed to your computer and use it in GitHub Desktop.
React wrapper for vanilla anchor element considering `href` to internal pages
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { AnchorHTMLAttributes, MouseEvent as ReactMouseEvent, useCallback } from 'react' | |
const InternalUrlRegexp = /^\.?\// | |
const StartingDotRegexp = /^\./ | |
export function Anchor({ | |
children, | |
href, | |
onClick, | |
...rest | |
}: AnchorHTMLAttributes<HTMLAnchorElement>) { | |
const handleClick = useCallback( | |
(e: ReactMouseEvent<HTMLAnchorElement, MouseEvent>) => { | |
onClick?.(e) | |
const isAbsoluteHost = href?.startsWith(location.origin) | |
const isRelativeHost = href?.match(InternalUrlRegexp) | |
if (!isAbsoluteHost && !isRelativeHost) return | |
e.preventDefault() | |
if (isAbsoluteHost) { | |
history.pushState(null, '', href) | |
} else { | |
history.pushState(null, '', origin + href?.replace(StartingDotRegexp, '')) | |
} | |
}, | |
[onClick], | |
) | |
return ( | |
<a onClick={handleClick} href={href} {...rest}> | |
{children} | |
</a> | |
) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
When using react, it's verty tidious to disable default behavior of anchor element while preserving accessibilities. You may want to develop your own routing system while not using react-router kind of things.
If you're using next.js, DO NOT use this becasue
<Link>
fromnext/link
will does it for you. Also this may break next.js's internal routing invariants inside of the history objects.Behavior
href
starts with/
or./
, it push url whichhref
is appended, withnull
history state.href
starts with currentorigin
, it push givenhref
withnull
history state.Note
onClick
is called before history is pushed.Usage