fix: remove trailing slash from site.url to prevent double-slash URLs

site.url had a trailing slash (added for Mastodon rel=me verification),
which caused double slashes in all URL constructions like
{{ site.url }}/auth → https://rmendes.net//auth

This broke IndieAuth login — indielogin.com read the authorization_endpoint
link tag with //auth and redirected users there, which 404'd in nginx.

Split into site.url (no slash, for URL construction) and site.me /
site.author.url (with slash, for Mastodon rel=me strict matching).

Also fixed twitter:image meta tags to use smart slash logic matching
the og:image pattern (check if path starts with / before prepending one).
This commit is contained in:
Ricardo
2026-02-24 16:18:52 +01:00
parent 20f7823ee1
commit 910889cde8
2 changed files with 10 additions and 8 deletions

View File

@@ -62,14 +62,16 @@ function buildSocialFromFeeds() {
return links;
}
// Ensure URL has trailing slash (Mastodon rel="me" verification uses strict string match)
const siteUrl = (process.env.SITE_URL || "https://example.com").replace(/\/$/, "") + "/";
// site.url: no trailing slash — used as URL base for path concatenation ({{ site.url }}/path)
// site.me / site.author.url: trailing slash — Mastodon rel="me" requires exact match
const siteUrlBase = (process.env.SITE_URL || "https://example.com").replace(/\/$/, "");
const siteUrlWithSlash = siteUrlBase + "/";
export default {
// Basic site info
name: process.env.SITE_NAME || "My IndieWeb Blog",
url: siteUrl,
me: siteUrl,
url: siteUrlBase,
me: siteUrlWithSlash,
locale: process.env.SITE_LOCALE || "en",
description:
process.env.SITE_DESCRIPTION ||
@@ -78,7 +80,7 @@ export default {
// Author info (shown in h-card, about page, etc.)
author: {
name: process.env.AUTHOR_NAME || "Blog Author",
url: siteUrl,
url: siteUrlWithSlash,
avatar: process.env.AUTHOR_AVATAR || "/images/default-avatar.svg",
title: process.env.AUTHOR_TITLE || "",
bio: process.env.AUTHOR_BIO || "Welcome to my IndieWeb blog.",

View File

@@ -45,11 +45,11 @@
<meta name="twitter:title" content="{{ ogTitle }}">
<meta name="twitter:description" content="{{ ogDesc }}">
{% if ogPhoto and ogPhoto != "" and (ogPhoto | length) > 10 %}
<meta name="twitter:image" content="{% if 'http' in ogPhoto %}{{ ogPhoto }}{% else %}{{ site.url }}/{{ ogPhoto }}{% endif %}">
<meta name="twitter:image" content="{% if 'http' in ogPhoto %}{{ ogPhoto }}{% else %}{{ site.url }}{% if ogPhoto[0] != '/' %}/{% endif %}{{ ogPhoto }}{% endif %}">
{% elif image and image != "" and (image | length) > 10 %}
<meta name="twitter:image" content="{% if 'http' in image %}{{ image }}{% else %}{{ site.url }}/{{ image }}{% endif %}">
<meta name="twitter:image" content="{% if 'http' in image %}{{ image }}{% else %}{{ site.url }}{% if image[0] != '/' %}/{% endif %}{{ image }}{% endif %}">
{% elif contentImage and contentImage != "" and (contentImage | length) > 10 %}
<meta name="twitter:image" content="{% if 'http' in contentImage %}{{ contentImage }}{% else %}{{ site.url }}/{{ contentImage }}{% endif %}">
<meta name="twitter:image" content="{% if 'http' in contentImage %}{{ contentImage }}{% else %}{{ site.url }}{% if contentImage[0] != '/' %}/{% endif %}{{ contentImage }}{% endif %}">
{% elif hasOgImage %}
<meta name="twitter:image" content="{{ site.url }}/og/{{ ogSlug }}.png">
{% endif %}