Skip to content

Commit e69872e

Browse files
committed
feat: implement ID redirect worker with resource mapping and redirection logic; add configuration for worker in wrangler.toml
1 parent fea3fd0 commit e69872e

4 files changed

Lines changed: 60 additions & 32 deletions

File tree

public/yourselftoscience.pdf

0 Bytes
Binary file not shown.

src/app/resource/[slug]/page.js

Lines changed: 13 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// src/app/resource/[slug]/page.js
22
import { resources } from '@/data/resources';
3-
import { redirect, notFound } from 'next/navigation';
3+
import { notFound } from 'next/navigation';
44
import Link from 'next/link';
55
import {
66
FaExternalLinkAlt, FaHeart, FaDollarSign, FaQuestionCircle, FaUniversity,
@@ -9,54 +9,35 @@ import {
99
FaUserFriends, FaCoins, FaListOl, FaUserShield, FaArrowRight
1010
} from 'react-icons/fa';
1111

12-
// THIS IS THE KEY FIX:
13-
// We tell Next.js to generate a page for every slug AND every ID.
14-
// This ensures that links with UUIDs do not result in a 404 error after deployment.
12+
// This now correctly tells Next.js to build a static page for every SLUG.
1513
export async function generateStaticParams() {
16-
const paths = [];
17-
resources.forEach(resource => {
18-
// Add path for the human-readable slug
19-
paths.push({ slug: resource.slug });
20-
// Add path for the permanent ID
21-
if (resource.id) {
22-
paths.push({ slug: resource.id });
23-
}
24-
});
25-
return paths;
14+
return resources.map((resource) => ({
15+
slug: resource.slug,
16+
}));
2617
}
2718

19+
// Generate metadata based solely on the SLUG.
2820
export async function generateMetadata({ params }) {
29-
const resource = resources.find(p => p.slug === params.slug || p.id === params.slug);
21+
const resource = resources.find(p => p.slug === params.slug);
3022
if (!resource) {
31-
return {
32-
title: 'Resource Not Found',
33-
};
23+
return { title: 'Resource Not Found' };
3424
}
3525
const title = `${resource.title} - Yourself To Science`;
3626
const description = resource.description || `Learn more about contributing to ${resource.title}.`;
3727
const canonicalUrl = `https://yourselftoscience.org/resource/${resource.slug}`;
38-
28+
3929
return {
4030
title,
4131
description,
42-
alternates: {
43-
canonical: canonicalUrl,
44-
},
32+
alternates: { canonical: canonicalUrl },
4533
};
4634
}
4735

4836
export default function ResourcePage({ params }) {
49-
const resource = resources.find(p => p.slug === params.slug || p.id === params.slug);
50-
37+
// Find the resource using its SLUG.
38+
const resource = resources.find(p => p.slug === params.slug);
5139
if (!resource) {
52-
notFound(); // Correctly show a 404 if no resource is found
53-
}
54-
55-
// THIS IS THE SECOND FIX:
56-
// If the page was accessed via its ID, issue a permanent redirect
57-
// to the canonical URL that uses the slug.
58-
if (params.slug === resource.id && resource.id !== resource.slug) {
59-
redirect(`/resource/${resource.slug}`, 'replace');
40+
notFound();
6041
}
6142

6243
// --- All of your UI code below remains untouched ---

workers/redirect.js

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
let resourceMap = null;
2+
3+
async function getResourceMap() {
4+
if (resourceMap) return resourceMap;
5+
try {
6+
const response = await fetch('https://yourselftoscience.org/resources.json');
7+
if (!response.ok) throw new Error(`Failed to fetch resources: ${response.statusText}`);
8+
const resources = await response.json();
9+
const newMap = new Map();
10+
for (const resource of resources) {
11+
if (resource.id && resource.slug) {
12+
newMap.set(resource.id, resource.slug);
13+
}
14+
}
15+
resourceMap = newMap;
16+
return resourceMap;
17+
} catch (error) {
18+
console.error('Error building resource map:', error);
19+
return new Map();
20+
}
21+
}
22+
23+
export default {
24+
async fetch(request) {
25+
const { pathname } = new URL(request.url);
26+
const pathParts = pathname.split('/').filter(Boolean);
27+
28+
// If the URL matches /resource/<uuid>
29+
if (pathParts.length === 2 && pathParts[0] === 'resource') {
30+
const uuid = pathParts[1];
31+
const map = await getResourceMap();
32+
const slug = map.get(uuid);
33+
if (slug) {
34+
const destinationURL = `https://yourselftoscience.org/resource/${slug}`;
35+
return Response.redirect(destinationURL, 308);
36+
}
37+
}
38+
// Fallback in case no match is found.
39+
return Response.redirect('https://yourselftoscience.org', 301);
40+
},
41+
};

wrangler.toml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
name = "id-redirect-worker"
2+
main = "workers/redirect.js"
3+
compatibility_date = "2024-07-31"
4+
5+
[triggers]
6+
routes = ["id.yourselftoscience.org/*"]

0 commit comments

Comments
 (0)