Fix bug with external links and simplify analytics
All checks were successful
Build and Push Docker Image / build (push) Successful in 47s

This commit is contained in:
2026-04-21 15:28:10 -07:00
parent 1ea315543b
commit 38336301e9
3 changed files with 59 additions and 17 deletions

View File

@@ -15,11 +15,9 @@ export function ProfileBadge() {
<li> <li>
<a <a
href={urlLinkedIn} href={urlLinkedIn}
data-external
target="_blank" target="_blank"
rel="noopener" no-decorate='true'
aria-label="LinkedIn" aria-label="LinkedIn"
data-umami-event="NavToLinkedIn"
> >
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<path d="M20.447 20.452h-3.554v-5.569c0-1.328-.027-3.037-1.852-3.037-1.853 0-2.136 1.445-2.136 2.939v5.667H9.351V9h3.414v1.561h.046c.477-.9 1.637-1.85 3.37-1.85 3.601 0 4.267 2.37 4.267 5.455v6.286zM5.337 7.433c-1.144 0-2.063-.926-2.063-2.065 0-1.138.92-2.063 2.063-2.063 1.14 0 2.064.925 2.064 2.063 0 1.139-.925 2.065-2.064 2.065zm1.782 13.019H3.555V9h3.564v11.452zM22.225 0H1.771C.792 0 0 .774 0 1.729v20.542C0 23.227.792 24 1.771 24h20.451C23.2 24 24 23.227 24 22.271V1.729C24 .774 23.2 0 22.222 0h.003z"/> <path d="M20.447 20.452h-3.554v-5.569c0-1.328-.027-3.037-1.852-3.037-1.853 0-2.136 1.445-2.136 2.939v5.667H9.351V9h3.414v1.561h.046c.477-.9 1.637-1.85 3.37-1.85 3.601 0 4.267 2.37 4.267 5.455v6.286zM5.337 7.433c-1.144 0-2.063-.926-2.063-2.065 0-1.138.92-2.063 2.063-2.063 1.14 0 2.064.925 2.064 2.063 0 1.139-.925 2.065-2.064 2.065zm1.782 13.019H3.555V9h3.564v11.452zM22.225 0H1.771C.792 0 0 .774 0 1.729v20.542C0 23.227.792 24 1.771 24h20.451C23.2 24 24 23.227 24 22.271V1.729C24 .774 23.2 0 22.222 0h.003z"/>
@@ -28,11 +26,9 @@ export function ProfileBadge() {
</li> </li>
<li> <li>
<a href={urlX} <a href={urlX}
data-external
target="_blank" target="_blank"
rel="noopener" no-decorate='true'
aria-label="X (Twitter)" aria-label="X (Twitter)"
data-umami-event="NavToX"
> >
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<path d="M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z"/> <path d="M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z"/>
@@ -41,11 +37,9 @@ export function ProfileBadge() {
</li> </li>
<li> <li>
<a href={urlGit} <a href={urlGit}
data-external
target="_blank" target="_blank"
rel="noopener" no-decorate='true'
aria-label="GitHub / Gitea" aria-label="GitHub / Gitea"
data-umami-event="NavToGit"
> >
<div className="git-icon-wrapper"> <div className="git-icon-wrapper">
<svg className="icon-github" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"> <svg className="icon-github" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">

View File

@@ -21,16 +21,38 @@ async function loadContent(url: string, shouldScrollToTop: boolean = true) {
} }
function attachLinkHandlers() { function attachLinkHandlers() {
const links: NodeListOf<HTMLAnchorElement> = document.querySelectorAll('a:not([data-external])'); const currentDomain = window.location.hostname;
const links: NodeListOf<HTMLAnchorElement> = document.querySelectorAll('a');
const internalLinks = Array.from(links).filter(link => {
const linkDomain = new URL(link.href).hostname;
return linkDomain == currentDomain;
});
const externalLinks = Array.from(links).filter(link => {
const linkDomain = new URL(link.href).hostname;
return linkDomain !== currentDomain;
})
links.forEach(link => { links.forEach(link => {
link.onclick = async (e) => { //Internal Link, use history api
console.log('clicked', link.href); if (link.host == window.location.host) {
e.preventDefault(); link.onclick = async (e) => {
e.stopPropagation(); console.log('clicked', link.href);
e.stopImmediatePropagation(); e.preventDefault();
window.history.pushState({}, '', link.href); e.stopPropagation();
await loadContent(link.href, true); e.stopImmediatePropagation();
window.history.pushState({}, '', link.href);
await loadContent(link.href, true);
}
// External Link, add outbound link recording
} else {
const name = 'outbound-link-click';
if (!link.getAttribute('data-umami-event')) {
link.setAttribute('data-umami-event', name);
link.setAttribute('data-umami-event-url', link.href)
link.setAttribute('target', '_blank')
}
} }
}); });
} }

View File

@@ -552,6 +552,32 @@ a:hover {
text-decoration: underline; text-decoration: underline;
} }
a[target="_blank"]:not([no-decorate]) {
position: relative;
}
a[target="_blank"]:not([no-decorate])::after {
display: inline-block;
width: 0.75em;
height: 0.75em;
margin-left: 0.25em;
vertical-align: middle;
background-color: currentColor;
-webkit-mask-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 24 24' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cg id='Interface / External_Link'%3E%3Cpath id='Vector' d='M10.0002 5H8.2002C7.08009 5 6.51962 5 6.0918 5.21799C5.71547 5.40973 5.40973 5.71547 5.21799 6.0918C5 6.51962 5 7.08009 5 8.2002V15.8002C5 16.9203 5 17.4801 5.21799 17.9079C5.40973 18.2842 5.71547 18.5905 6.0918 18.7822C6.5192 19 7.07899 19 8.19691 19H15.8031C16.921 19 17.48 19 17.9074 18.7822C18.2837 18.5905 18.5905 18.2839 18.7822 17.9076C19 17.4802 19 16.921 19 15.8031V14M20 9V4M20 4H15M20 4L13 11' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3C/path%3E%3C/g%3E%3C/svg%3E");
mask-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 24 24' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cg id='Interface / External_Link'%3E%3Cpath id='Vector' d='M10.0002 5H8.2002C7.08009 5 6.51962 5 6.0918 5.21799C5.71547 5.40973 5.40973 5.71547 5.21799 6.0918C5 6.51962 5 7.08009 5 8.2002V15.8002C5 16.9203 5 17.4801 5.21799 17.9079C5.40973 18.2842 5.71547 18.5905 6.0918 18.7822C6.5192 19 7.07899 19 8.19691 19H15.8031C16.921 19 17.48 19 17.9074 18.7822C18.2837 18.5905 18.5905 18.2839 18.7822 17.9076C19 17.4802 19 16.921 19 15.8031V14M20 9V4M20 4H15M20 4L13 11' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3C/path%3E%3C/g%3E%3C/svg%3E");
-webkit-mask-repeat: no-repeat;
mask-repeat: no-repeat;
-webkit-mask-position: center;
mask-position: center;
-webkit-mask-size: contain;
mask-size: contain;
color: var(--text-secondary);
}
a[target="_blank"]:not([no-decorate]):hover::after {
color: var(--text-primary);
}
h1 { h1 {
margin-top: 0; margin-top: 0;
} }