Lien de menu de navigation - DsfrNavigationMenuLink 
🌟 Introduction 
Le lien de menu de navigation est un composant qui crée un lien cliquable dans un menu de navigation. Il gère automatiquement les liens externes et internes avec le routeur Vue.
Le composant DsfrNavigationMenuLink crée un lien de navigation avec support des icônes, gestion automatique des liens externes/internes, et intégration avec le système de navigation du header.
Important
Ce composant NE devrait PAS être utilisé directement, il est utilisé en interne par son parent DsfrNavigationMenu
📐 Structure 
Le lien de menu de navigation crée dynamiquement :
- un élément <a>pour les liens externes (commençant parhttp)
- un <RouterLink>pour les liens internes avec gestion automatique du routeur Vue
- une icône optionnelle avec support des icônes DSFR (fr-icon-*) ou Iconify
- la classe CSS fr-nav__linkpour le styling DSFR
🛠️ Props 
| nom | type | défaut | obligatoire | description | 
|---|---|---|---|---|
| id | string | () => useRandomId(...) | Identifiant unique pour le lien | |
| to | string | RouteLocationRaw | '#' | Destination du lien (URL ou objet route Vue) | |
| text | string | '' | Texte affiché du lien | |
| icon | string | VIcon['$props'] | undefined | Icône à afficher (nom Iconify ou props VIcon) | |
| onClick | Function | () => undefined | Fonction appelée lors du clic sur le lien | 
📡 Événements 
DsfrNavigationMenuLink déclenche l'événement suivant :
| nom | donnée (payload) | description | 
|---|---|---|
| toggleId | string | Émis lors du clic pour gérer l'état des menus | 
🧩 Slots 
DsfrNavigationMenuLink n'a pas de slots personnalisés.
📝 Exemples 
Exemple d'utilisation de DsfrNavigationMenuLink dans un menu :
vue
<template>
  <DsfrNavigationMenu title="Liens utiles">
    <DsfrNavigationMenuItem>
      <DsfrNavigationMenuLink
        to="/accueil"
        text="Page d'accueil"
        icon="ri-home-line"
      />
    </DsfrNavigationMenuItem>
    <DsfrNavigationMenuItem>
      <DsfrNavigationMenuLink
        to="https://www.service-public.fr"
        text="Service Public"
        icon="fr-icon-external-link-line"
      />
    </DsfrNavigationMenuItem>
  </DsfrNavigationMenu>
</template>⚙️ Code source du composant 
vue
<script lang="ts" setup>
import type { DsfrNavigationMenuLinkProps } from './DsfrNavigation.types'
import { computed, hasInjectionContext, inject } from 'vue'
import { useRandomId } from '../../utils/random-utils'
import { registerNavigationLinkKey } from '../DsfrHeader/injection-key'
import VIcon from '../VIcon/VIcon.vue'
export type { DsfrNavigationMenuLinkProps }
const props = withDefaults(defineProps<DsfrNavigationMenuLinkProps>(), {
  id: () => useRandomId('menu-link'),
  icon: undefined,
  onClick: () => undefined,
  text: '',
  to: '#',
})
defineEmits<{ (event: 'toggleId', id: string): void }>()
const isExternal = computed(() => typeof props.to === 'string' && props.to.startsWith('http'))
const dsfrIcon = computed(() => props.icon && typeof props.icon === 'string' && props.icon.startsWith('fr-icon-'))
const defaultScale = 2
const iconProps = computed(() => (dsfrIcon.value || !props.icon)
  ? undefined
  : (typeof props.icon === 'string')
      ? { scale: defaultScale, name: props.icon }
      : { scale: defaultScale, ...((props.icon as Record<string, string>) || {}) },
)
const useHeader = hasInjectionContext() ? inject(registerNavigationLinkKey)! : undefined
const closeModal = useHeader?.() ?? (() => {})
</script>
<template>
  <a
    v-if="isExternal"
    class="fr-nav__link"
    data-testid="nav-external-link"
    :href="(to as string)"
    @click="$emit('toggleId', id); onClick($event)"
  >
    {{ text }}
  </a>
  <RouterLink
    v-else
    class="fr-nav__link"
    data-testid="nav-router-link"
    :to="to"
    :class="{
      [String(icon)]: dsfrIcon,
    }"
    @click="closeModal(); $emit('toggleId', id); onClick?.($event)"
  >
    <VIcon
      v-if="icon && iconProps"
      v-bind="iconProps"
    />
    {{ text }}
  </RouterLink>
</template>ts
import type { RouteLocationRaw } from 'vue-router'
export type DsfrNavigationMenuLinkProps = {
  id?: string
  to?: string | RouteLocationRaw
  text?: string
  icon?: string
  onClick?: ($event: MouseEvent) => void
}
export type DsfrNavigationMenuItemProps = {
  id?: string
  active?: boolean
}
export type DsfrNavigationMenuProps = {
  id?: string
  title: string
  links?: DsfrNavigationMenuLinkProps[]
  expandedId?: string
  active?: boolean
}
export type DsfrNavigationItemProps = {
  id?: string
  active?: boolean
}
export type DsfrNavigationMegaMenuCategoryProps = {
  title: string
  active?: boolean
  links: DsfrNavigationMenuLinkProps[]
}
export type DsfrNavigationMegaMenuProps = {
  id?: string
  title: string
  description?: string
  link?: { to: RouteLocationRaw, text: string }
  menus?: DsfrNavigationMegaMenuCategoryProps[]
  expandedId?: string
  active?: boolean
}
export type DsfrNavigationMenuLinks = (DsfrNavigationMenuLinkProps | DsfrNavigationMegaMenuProps | DsfrNavigationMenuProps)[]
export type DsfrNavigationProps = {
  id?: string
  label?: string
  navItems: (
    DsfrNavigationMenuLinkProps
    | DsfrNavigationMenuProps
    | DsfrNavigationMegaMenuProps
  )[]
}