Link

A styled anchor component for navigation with built-in icon support

Usage

import { Link } from '@hareui/vue'
<script setup lang="ts">import { Link } from '@hareui/vue'</script><template>  <Link href="#" icon>    Call to action  </Link></template>

Anatomy

<template>
  <!-- `icon` shows HeroUI's external-link arrow (Link.Icon); `#icon` replaces it -->
  <Link href="#" icon>
    Call to action
  </Link>
</template>

Examples

Icon Placement

<script setup lang="ts">import { Link } from '@hareui/vue'</script><template>  <div class="flex flex-col gap-3">    <Link href="#" icon>      Icon at end (default)    </Link>    <Link class="gap-1" href="#" icon icon-placement="start">      Icon at start    </Link>  </div></template>

Text Decoration with Tailwind CSS

Link is underlined on hover by default. Use Tailwind CSS text-decoration utilities to make the underline always visible, remove it entirely, or customize its color, style, thickness, and offset.

<script setup lang="ts">import { Link } from '@hareui/vue'</script><template>  <div class="flex flex-col gap-6">    <div class="flex flex-col gap-2">      <p class="text-sm font-medium text-muted">        Default hover underline      </p>      <Link href="#" icon>        Hover to see the underline      </Link>    </div>    <div class="flex flex-col gap-2">      <p class="text-sm font-medium text-muted">        Always visible underline      </p>      <Link class="underline" href="#" icon>        Underline always visible      </Link>    </div>    <div class="flex flex-col gap-2">      <p class="text-sm font-medium text-muted">        No underline      </p>      <Link class="no-underline" href="#" icon>        Link without any underline      </Link>    </div>    <div class="flex flex-col gap-2">      <p class="text-sm font-medium text-muted">        Changing the underline offset      </p>      <div class="flex flex-col gap-3">        <Link class="underline-offset-1" href="#" icon>          Offset 1 (1px space)        </Link>        <Link class="underline-offset-2" href="#" icon>          Offset 2 (2px space)        </Link>        <Link class="underline-offset-3" href="#" icon>          Offset 3 (3px space)        </Link>        <Link class="underline-offset-4" href="#" icon>          Offset 4 (4px space)        </Link>      </div>    </div>  </div></template>

Text Decoration Line:

  • underline - Always visible underline
  • no-underline - Remove underline
  • default Link styles - Underline appears on hover

Text Decoration Color:

  • decoration-accent, decoration-muted, etc. - Set underline color using theme colors
  • decoration-muted/50 - Use opacity modifiers for semi-transparent underlines

Text Decoration Style:

  • decoration-solid - Solid line (default)
  • decoration-double - Double line
  • decoration-dotted - Dotted line
  • decoration-dashed - Dashed line
  • decoration-wavy - Wavy line

Text Decoration Thickness:

  • decoration-1, decoration-2, decoration-4, etc. - Control underline thickness

Underline Offset:

  • underline-offset-1, underline-offset-2, underline-offset-4, etc. - Adjust spacing between text and underline

For more details, see the Tailwind CSS documentation:

Custom Icon

<script setup lang="ts">import { Icon } from '@iconify/vue'import { Link } from '@hareui/vue'</script><template>  <div class="flex flex-col gap-3">    <Link href="#" :ui="{ icon: 'ms-1.5 size-3' }">      External link      <template #icon>        <Icon icon="gravity-ui:arrow-up-right-from-square" />      </template>    </Link>    <Link class="gap-1" href="#" :ui="{ icon: 'size-3' }">      Go to page      <template #icon>        <Icon icon="gravity-ui:link" />      </template>    </Link>  </div></template>

Render Function

Call to action
<script setup lang="ts">import { Link } from '@hareui/vue'import { defineComponent, h } from 'vue'const CustomSpan = defineComponent((_, { attrs, slots }) => () => h('span', { ...attrs, 'data-custom': 'foo' }, slots.default?.()))</script><template>  <Link :as="CustomSpan" href="#" icon>    Call to action  </Link></template>

Customization

Tailwind CSS

<script setup lang="ts">import { Link } from '@hareui/vue'</script><template>  <Link    class="font-medium text-neutral-700 underline decoration-neutral-300/80 underline-offset-4 transition-colors hover:text-neutral-900 dark:text-neutral-300 dark:decoration-neutral-600/80 dark:hover:text-neutral-100"    href="#"    icon  >    Call to action  </Link></template>

Global theme override

app.use(createHareUI({
  ui: {
    link: {
      slots: {
        base: 'font-semibold',
        icon: 'opacity-100',
      },
    },
  },
}))

Styling Reference

Slots

  • base → [data-slot="link"] – Base link styles with hover underline
  • icon → [data-slot="link-icon"] – Link icon wrapper (data-default-icon="true" while it shows the built-in arrow)

Interactive States

  • Focus: :focus-visible
  • Hover: :hover
  • Pressed: :active
  • Disabled: [aria-disabled="true"]

API Reference

Props

PropTypeDefaultDescription
asAsTag | Component"a"The element or component to render as, e.g. a router link component.
hrefstring-The URL the link points to.
disabledboolean-Whether the link is disabled: sets aria-disabled and blocks navigation.
iconbooleanfalseShow the icon (HeroUI's Link.Icon). Defaults to the external-link arrow; fill #icon to replace it.
iconPlacement"start" | "end""end"Which side of the text the icon goes on.
uiComponentSlots<{ slots: { base: string; icon: string; }; }>-Per-slot class overrides.

Slots

SlotPropsDescription
defaultanyThe link text.
iconanyCustom icon content; renders the icon wrapper even when icon is not set.

Using with Routing Libraries

Pass a router link component to as; the Link styles and icon stay the same:

<script setup lang="ts">
import { Link } from '@hareui/vue'
import { RouterLink } from 'vue-router'
</script>

<template>
  <Link :as="RouterLink" to="/about">
    About Page
  </Link>
</template>

On this page

No Headings