diff --git a/components/molecules/VRoadizLink/Default.stories.vue b/components/molecules/VRoadizLink/Default.stories.vue
index 07869cb..6ac8ec0 100644
--- a/components/molecules/VRoadizLink/Default.stories.vue
+++ b/components/molecules/VRoadizLink/Default.stories.vue
@@ -16,7 +16,7 @@ const currentBaseUrl = computed(() => (window?.origin ? joinURL(window.origin, '
(window?.origin ? joinURL(window.origin, '
-
+
@@ -42,7 +42,7 @@ const currentBaseUrl = computed(() => (window?.origin ? joinURL(window.origin, '
-
+
External Link
diff --git a/components/molecules/VRoadizLink/Schemes.stories.vue b/components/molecules/VRoadizLink/Schemes.stories.vue
new file mode 100644
index 0000000..84ae77c
--- /dev/null
+++ b/components/molecules/VRoadizLink/Schemes.stories.vue
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/components/molecules/VRoadizLink/VRoadizLink.vue b/components/molecules/VRoadizLink/VRoadizLink.vue
index 56d86d4..41533e6 100644
--- a/components/molecules/VRoadizLink/VRoadizLink.vue
+++ b/components/molecules/VRoadizLink/VRoadizLink.vue
@@ -4,7 +4,6 @@ import { h, type PropType } from 'vue'
import type { NuxtLinkProps } from '#app/components/nuxt-link'
import { NuxtLink } from '#components'
import type { ReachableItem } from '~/types/app'
-import { isInternalUrl } from '~/utils/url'
export const vRoadizLinkProps = {
label: [String, Boolean],
@@ -21,47 +20,57 @@ export default defineComponent({
setup(props, { attrs, slots }) {
const reference = computed(() => {
if (!props.reference) return
- return Array.isArray(props.reference) ? props.reference[0] : props.reference
- })
- const url = computed(() => {
- return props.url || reference.value?.url || props.document?.relativePath
+ return Array.isArray(props.reference) ? props.reference[0] : props.reference
})
const runtimeConfig = useRuntimeConfig()
const siteUrl = runtimeConfig?.public?.site.url
- const isInternal = computed(() => isInternalUrl(url.value, siteUrl))
- const isExternal = computed(() => !!url.value && !isInternal.value)
- const isDownload = computed(() => !!url.value && !isExternal.value && !!props.document?.relativePath)
-
const attributes = computed(() => {
- const mergedAttrs = { ...attrs, ...props.nuxtLinkProps }
- if (!url.value) return mergedAttrs
+ const defaultAttrs = { ...attrs, ...props.nuxtLinkProps }
- if (isDownload.value) {
- Object.assign(mergedAttrs, {
+ // Download
+ if (props.document?.relativePath) {
+ return {
+ ...defaultAttrs,
href: useRoadizDocumentUrl(props.document?.relativePath),
target: attrs?.target || '_blank',
- rel: attrs?.rel || 'noopener',
+ rel: attrs?.rel || 'noopener noreferrer',
download: '',
- })
+ }
}
- else if (isExternal.value) {
- Object.assign(mergedAttrs, {
+
+ // External link
+ if (props.url && isExternalUrl(props.url, siteUrl)) {
+ return {
+ ...defaultAttrs,
href: props.url,
target: attrs?.target || '_blank',
- rel: attrs?.rel || 'noopener',
- })
+ rel: attrs?.rel || 'noopener noreferrer',
+ }
}
- else if (isInternal.value) {
+
+ // Internal link
+ const internalUrl = props.url && isInternalURL(props.url, siteUrl) ? props.url : reference.value && isInternalURL(reference.value.url, siteUrl) ? reference.value.url : undefined
+
+ if (internalUrl) {
// Prevent NuxtLink to add rel attrs if it is absolute internal url
- Object.assign(mergedAttrs, {
- to: url.value?.replace(siteUrl, ''), // Force relative path
- })
+ return {
+ ...defaultAttrs,
+ to: internalUrl?.replace(siteUrl, ''), // Force relative path
+ }
+ }
+
+ // Other kind of links (mailto, tel, javascript, etc.)
+ if (props.url) {
+ return {
+ ...defaultAttrs,
+ to: props.url,
+ }
}
- return mergedAttrs
+ return defaultAttrs
})
return () => {
diff --git a/utils/url.ts b/utils/url.ts
index fb8970a..18b2f00 100644
--- a/utils/url.ts
+++ b/utils/url.ts
@@ -4,12 +4,18 @@ export function encodeUrlParams(params: object): string {
.join('&')
}
-export function isRelativeUrl(url: string | undefined | null) {
- return url?.charAt(0) === '/' || url?.charAt(0) === '#'
+export function isHttpUrlScheme(url: string) {
+ return url.startsWith('http://') || url.startsWith('https://')
}
-export function isInternalUrl(url: string | undefined | null, siteUrl?: string) {
- if (!url) return false
+export function isRelativeUrl(url: string) {
+ return url.charAt(0) === '/'
+}
+export function isInternalURL(url: string, siteUrl?: string) {
return isRelativeUrl(url) || (siteUrl && url.startsWith(siteUrl))
}
+
+export function isExternalUrl(url: string, siteUrl?: string) {
+ return isHttpUrlScheme(url) && !isInternalURL(url, siteUrl)
+}