From 26421be4e64c713e5b17128843aa0c1b99d22731 Mon Sep 17 00:00:00 2001 From: Ajax Davis Date: Mon, 29 Dec 2025 22:16:15 +1000 Subject: [PATCH] fix: URL-decode slug to handle scoped packages with encoded @ symbol MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The @ in scoped package names was being URL-encoded to %40, causing parseSlug to treat them as unscoped packages. Now we decode the slug components first. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- apps/web/src/app/tool/[...slug]/page.tsx | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/apps/web/src/app/tool/[...slug]/page.tsx b/apps/web/src/app/tool/[...slug]/page.tsx index 9ffed80..0937f29 100644 --- a/apps/web/src/app/tool/[...slug]/page.tsx +++ b/apps/web/src/app/tool/[...slug]/page.tsx @@ -13,14 +13,17 @@ interface ToolDetailPageProps { * Parse the URL slug to extract package name and optional export name */ function parseSlug(slug: string[]): { packageName: string; exportName?: string } { - if (slug[0]?.startsWith('@')) { + // URL-decode slug components (@ comes as %40) + const decodedSlug = slug.map((s) => decodeURIComponent(s)); + + if (decodedSlug[0]?.startsWith('@')) { // Scoped package: ['@scope', 'package', 'exportName?'] - const packageName = slug.slice(0, 2).join('/'); - const exportName = slug[2]; + const packageName = decodedSlug.slice(0, 2).join('/'); + const exportName = decodedSlug[2]; return { packageName, exportName }; } // Unscoped: ['package', 'exportName?'] - return { packageName: slug[0] || '', exportName: slug[1] }; + return { packageName: decodedSlug[0] || '', exportName: decodedSlug[1] }; } /**