Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@
"generate-funding-schema": "node scripts/generate-funding-schema.js",
"prebuild": "npm run generate-og-images && npm run generate-contrib-data && npm run generate-hubspot-data && npm run generate-funding-schema",
"dev": "npm run prebuild && npx vite dev",
"build:web": "npx vite build",
"dev:no-prebuild": "npx vite dev",
"build:no-prebuild": "npx vite build",
"build": "npm run prebuild && npx vite build",
"preview": "npx vite preview",
"deploy": "gh-pages -d build -t true"
Expand Down
9 changes: 5 additions & 4 deletions src/hooks.server.js
Original file line number Diff line number Diff line change
Expand Up @@ -384,10 +384,11 @@ async function transformHtml(request, response, url) {
let transformedHtml = html;

// Only transform image URLs in development mode
if (!building) {
debugLog("🛠️ Development mode: transforming relative image URLs");
transformedHtml = transformImageUrls(transformedHtml, url);
}
// DISABLED: This was causing double path transformations on Netlify
// if (!building) {
// debugLog("🛠️ Development mode: transforming relative image URLs");
// transformedHtml = transformImageUrls(transformedHtml, url);
// }

// Only inject meta tags during build or for social media crawlers
if (building || isSocialMediaCrawler) {
Expand Down
4 changes: 2 additions & 2 deletions src/lib/blocks/Blog.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@
>
<a
class="post-link"
href="{base}/blog/{post.path}"
href="{base}/blog/{post.path}?from={pageNum === 1 ? 'blog' : `blog/${pageNum}`}"
title={post.meta.title}
>
{post.meta.title}
Expand Down Expand Up @@ -112,7 +112,7 @@
</p>
<a
class="block text-right mt-4"
href="{base}/blog/{post.path}"
href="{base}/blog/{post.path}?from={pageNum === 1 ? 'blog' : `blog/${pageNum}`}"
title={post.meta.title}
>
{$_("config.blog.readMore")}&hellip;
Expand Down
5 changes: 2 additions & 3 deletions src/lib/blocks/Header.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,7 @@
<li class="menu-item">
<a
class="menu-link h-20 grid items-center uppercase text-sm tracking-wider before:h-1 before:hover:bg-red-berry-900"
class:before:bg-red-berry-900={$page.url.pathname ===
item.href}
class:before:bg-red-berry-900={$page.url.pathname === item.href || $page.url.pathname.startsWith(item.href + '/')}
href={item.href}
target={item.target}
data-sveltekit-preload-data>{item.text}</a
Expand Down Expand Up @@ -112,7 +111,7 @@
<li>
<a
class="menu-link mobile block py-8 uppercase text-2xl tracking-wider no-underline"
class:text-red-berry-900={$page.url.pathname === item.href}
class:text-red-berry-900={$page.url.pathname === item.href || $page.url.pathname.startsWith(item.href + '/')}
href={item.href}
target={item.target}
on:click={toggleMenu}>{item.text}</a
Expand Down
79 changes: 75 additions & 4 deletions src/lib/blocks/Post.svelte
Original file line number Diff line number Diff line change
@@ -1,22 +1,93 @@
<script>
import { browser } from "$app/environment";
import { fetchAuthorsMetadata, formattedPubDate } from "$lib/utils";
import { onMount } from "svelte";
import { formattedPubDate, fetchAuthorsMetadata } from "$lib/utils";
import { Icon } from "svelte-icons-pack";
import { BsChevronLeft } from "svelte-icons-pack/bs";

export let data, title, pub_date, author;
export const form = data;

let authorsMetadata = [];
let backToBlogUrl = "/blog";

onMount(async () => {
const postAuthors = author || [];
authorsMetadata = await fetchAuthorsMetadata(postAuthors);

// Determine the correct "back to blog" URL
if (browser) {
// Method 1: Check URL parameters first (most reliable)
const urlParams = new URLSearchParams(window.location.search);
const fromPage = urlParams.get("from");

if (fromPage) {
// Validate that it's a valid blog page
if (fromPage === "blog" || /^blog\/\d+$/.test(fromPage)) {
backToBlogUrl = `/${fromPage}`;
}
} else {
// Method 2: Check referrer
const referrer = document.referrer;

if (referrer) {
try {
const referrerUrl = new URL(referrer);
const referrerPath = referrerUrl.pathname;

// Check if referrer is from a blog page
if (referrerPath.startsWith("/blog")) {
// If it's a paginated blog page (e.g., /blog/2, /blog/3)
const blogPageMatch = referrerPath.match(/^\/blog\/(\d+)$/);
if (blogPageMatch) {
const pageNum = parseInt(blogPageMatch[1]);
if (pageNum > 1) {
backToBlogUrl = `/blog/${pageNum}`;
} else {
backToBlogUrl = "/blog";
}
} else if (referrerPath === "/blog") {
backToBlogUrl = "/blog";
}
}
} catch (error) {
console.warn("Error parsing referrer URL:", error);
}
}
}
}
});

// Function to handle back button click
function handleBackClick(event) {
if (browser) {
// If we have a specific back URL, use it
if (backToBlogUrl !== "/blog") {
// Let the normal link behavior work
return;
}

// Otherwise, try to go back in history
if (window.history.length > 1) {
window.history.back();
event.preventDefault();
}
}
}
</script>

<article class="container">
<article class="container mx-auto max-w-6xl">
<div class="my-20 xl:mt-32 xl:mb-20">
<a
href={backToBlogUrl}
on:click={handleBackClick}
class="flex items-center justify-center md:justify-start gap-1 button py-1 text-red-berry-900 dark:text-spring-wood-400 hover:text-red-berry-800 dark:hover:text-spring-wood-200 border-b border-spring-wood-300 pb-2 mb-8"
>
<Icon src={BsChevronLeft} />
Back to blog
</a>
<h1
class="text-2xl
class="text-3xl
md:text-4xl
lg:tracking-tight
xl:text-6xl
Expand All @@ -38,7 +109,7 @@
{#each authorsMetadata as authorMeta}
<div class="flex flex-col items-center gap-2">
{#if authorMeta.src}
<img class="w-24 h-24 rounded-full object-cover" src={authorMeta.src} alt={authorMeta.name} />
<img class="w-24 h-24 rounded-full object-cover bg-spring-wood-50" src={authorMeta.src} alt={authorMeta.name} />
{/if}
<div class="font-light text-center w-36">
{authorMeta.name}
Expand Down
30 changes: 25 additions & 5 deletions svelte.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -71,13 +71,13 @@ const blogImages = () => {
}
});

// Then handle raw HTML to catch any embedded <img> tags
// Then handle raw HTML to catch any embedded <img>, <video>, and <source> tags
visit(tree, "html", (node) => {
if (node.value && node.value.includes("<img")) {
if (node.value && (node.value.includes("<img") || node.value.includes("<video") || node.value.includes("<source"))) {
debugLog(`[BlogImages] Processing HTML node: ${node.value.substring(0, 100)}...`);
const originalHtml = node.value;

// Simple regex to transform image src attributes
// This is a basic approach - for a production system you'd want to use a proper HTML parser
// Transform image src attributes
node.value = node.value.replace(/src="([^"]+)"/g, (match, src) => {
// Skip external URLs and absolute paths
if (
Expand All @@ -93,10 +93,30 @@ const blogImages = () => {
// Create the new src with blog slug
const newSrc = `/blog/${slug}/${cleanPath}`;

debugLog(`[BlogImages] Transformed HTML img: ${src} -> ${newSrc}`);
debugLog(`[BlogImages] Transformed HTML src: ${src} -> ${newSrc}`);
return `src="${newSrc}"`;
});

// Transform video href attributes (for download links)
node.value = node.value.replace(/href="([^"]+)"/g, (match, href) => {
// Skip external URLs and absolute paths
if (
href.startsWith("http") ||
(href.startsWith("/") && !href.startsWith("/blog/"))
) {
return match;
}

// Clean the path
const cleanPath = href.startsWith("./") ? href.slice(2) : href;

// Create the new href with blog slug
const newHref = `/blog/${slug}/${cleanPath}`;

debugLog(`[BlogImages] Transformed HTML href: ${href} -> ${newHref}`);
return `href="${newHref}"`;
});

if (originalHtml !== node.value) {
debugLog("[BlogImages] HTML node was transformed");
}
Expand Down