Link
A link allows users to navigate to different pages or resources.
import { Link } from "@opengovsg/oui"export const Example = () => { return <Link href="#">This is a link</Link>}Usage
import { Link } from "@opengovsg/oui"<Link href="/page">Navigate to page</Link>Alternatively, install the component as local source via the shadcn CLI:
npx shadcn@latest add https://oui.open.gov.sg/r/link.jsonpnpm dlx shadcn@latest add https://oui.open.gov.sg/r/link.jsonnpx shadcn@latest add https://oui.open.gov.sg/r/link.jsonbunx --bun shadcn@latest add https://oui.open.gov.sg/r/link.jsonThe Link component is built on top of React Aria's Link. It supports navigation via the href prop, or custom press handling via the onPress prop.
To ensure the Link component uses your framework's client-side router (instead of full page navigations), you need to set up the
RouterProviderfromreact-aria-components. See the Next.js or Vite setup guides, or refer to the React Aria frameworks guide for other frameworks.
Examples
Color
Use the color prop to change the color of the link.
import { Link } from "@opengovsg/oui"export const Example = () => { return ( <div className="flex flex-col gap-4"> <Link href="#">Default</Link> <Link href="#" color="neutral"> Neutral </Link> </div> )}Adding icons
When adding multiple children (such as using an icon to the Link text) to the Link component, you might encounter some layout issues when using block level elements like div or svg. All children of the Link component automatically have the inline styles applied to them, but sizing and alignment of the start/endContent should still be handled by you manually.
import { ArrowRightIcon, ExternalLinkIcon } from "lucide-react"import { Link } from "@opengovsg/oui"export const Example = () => { return ( <div className="flex w-full flex-col gap-4"> <p className="inline"> This is a paragraph with an inline icon link:{" "} <Link href="#"> <ExternalLinkIcon className="mr-0.5 mb-1 size-4" /> External link </Link> , and this should flow naturally, since all children of Link are inline by default. Sizing and alignment of the start/endContent should be handled by you manually. </p> <p> <Link href="#"> Continue <ArrowRightIcon className="mb-0.5 ml-0.5 size-4" /> </Link> , which is a link with an icon at the end. Check out the code to see the custom styles on the icons. </p> </div> )}Using pseudo elements (e.g. for external link affordance)
You can use the ::before and ::after pseudo elements to add additional content to the Link, such as an external link icon.
import { Link } from "@opengovsg/oui"export const Example = () => { return ( <Link href="#" className="before:content-['→_'] after:content-['_↗']"> See code for this example </Link> )}Disabled
Use the isDisabled prop to disable the link.
import { Link } from "@opengovsg/oui"export const Example = () => { return ( <Link href="#" isDisabled> Disabled link </Link> )}Events
Links with an href will be handled by the browser, or via a client side router. Links without an href will be rendered as a <span role="link"> instead of an <a>. Use the onPress event to handle user interaction.
import { Link } from "@opengovsg/oui"export const Example = () => { return ( <Link onPress={() => alert("Pressed link")}> Click to trigger onPress event instead of navigation </Link> )}