-
Notifications
You must be signed in to change notification settings - Fork 63
Make VLink component that wraps around both external and internal links #879
Conversation
# Conflicts: # src/pages/image/_id.vue
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM! Still need to test this locally but I'm still excited for this 🎉 The only blocker right now is the attrs
destructuring... I wish there was an eslint rule to warn against that, I feel like 99% of the time it's probably not the right thing to do. Maybe that's wrong though.
src/components/VLink.vue
Outdated
const { app } = useContext() | ||
const isInternal = computed(() => attrs.href?.startsWith('/')) | ||
const linkComponent = computed(() => (isInternal.value ? 'NuxtLink' : 'a')) | ||
const { href, ...otherProperties } = attrs |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Destructuring these from attrs
will make their values non-reactive in the computed
for linkProperties
below. To maintain reactivity they need to stay as properties on props
or attrs
.
I noticed three more
|
# Conflicts: # src/components/AudioDetails/VAudioDetails.vue # src/components/FooterSection.vue
Use VLink in DownloadButton
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The MediaTag changes seem unrelated. Was it a faulty merge perhaps? 🤔
src/components/VLink.vue
Outdated
{ immediate: true } | ||
let linkProperties = computed(() => | ||
isInternal.value | ||
? { to: app?.localePath(props.href) ?? props.href } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In what case is app
null? 😱
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When testing 😆 That was probably a lazy hack to ensure tests pass without mocking the nuxt context :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh dear! I wish it was easier to set up a globally enabled mock of the nuxt stuff 🤔
Co-authored-by: sarayourfriend <24264157+sarayourfriend@users.noreply.github.com>
Do you mean This PR is kind of very small: adding one component, but it touches so many files! |
Relabelling as "priority: medium" as the linked issue is actually fixed in the main branch and this is more of an improvement. |
Oh sorry, I was looking specifically at the merge commit, not the full diff for the PR 🤦 Anyway, it looks like making |
…nverse-frontend into add/bigger_vlink_component
Thank you for relabelling, I was thinking about making it a |
# Conflicts: # src/components/VMigrationNotice.vue
In the single media item detail pages we have some links that are created before the href values are available (while the image/audio is being fetched). To make VLink component handle links which set Another solution could be to use
What do you think, @WordPress/openverse-frontend ? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM! Things no longer crash because of this (there are still other crashes but unrelated to this change 👍)
src/components/VLink.vue
Outdated
@@ -21,19 +23,26 @@ export default defineComponent({ | |||
props: { | |||
href: { | |||
type: String, | |||
required: true, | |||
validator: (v) => !['', '#'].includes(v), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: I think we can keep the validator, otherwise accidental long-lived invalid href
values won't ever get caught.
@obulat a solution I've used in past projects to easily identify "bad links" is to add some kind of horrific inline-styles to them that make them obviously stand out. Something like |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm! I've clicked around pretty extensively and text searched for raw <a>
tags, in the repo, and didn't find anything that shouldn't be there.
Question for @WordPress/openverse-frontend: Does anyone know of an eslint rule we could introduce to warn on raw <a>
tag usage in our Vue templates?
@zackkrida The |
# Conflicts: # src/components/VMediaInfo/VCopyLicense.vue
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@obulat You were right! I forgot about the untouched links on internal pages. It's great we can now be safe about external links with these changes 🚀
Fixes
Fixes #468 by @obulat
Description
This PR supercedes #468, based on @krysal 's comment about wrapping internal links, too.
Now,
VLink
is a wrapper component that should be used for all links. It determines whether the link is internal or external by checking if thehref
attr starts with/
.External links:
a
element.target='_blank'
that allows the links to open in another tab, instead of causing errors in an iframe.rel='noopener noreferrer' to prevent some referrer vulnerabilities in older browsers (
target='_blank'` is enough for modern browsers)Internal links:
NuxtLink
component.href
inapp.localePath
to ensure that the correct locale is used, and pass it as theto
prop toNuxtLink
.This PR moves the warning for missing
href
fromVButton
toVLink
, soVButton
doesn't have to handle the lack ofhref
property.Testing Instructions
Run the app and test out internal links and external links. Also check that the links in the navbar (pages) work as expected. External links should always open in a new tab.
Checklist
Update index.md
).main
) or a parent feature branch.Developer Certificate of Origin
Developer Certificate of Origin