diff --git a/package.json b/package.json index 7af4e1977d2..a721c1fed26 100644 --- a/package.json +++ b/package.json @@ -229,6 +229,7 @@ "make-plural": "^7.0.0", "ms": "^2.1.3", "multicodec": "^3.0.1", + "multiformats": "^13.0.1", "multihashes": "^4.0.2", "nock": "^13.3.3", "node-vibrant": "^3.2.1-alpha.1", diff --git a/src/components/IPFSSubpathRedirect.tsx b/src/components/IPFSSubpathRedirect.tsx new file mode 100644 index 00000000000..edef3594054 --- /dev/null +++ b/src/components/IPFSSubpathRedirect.tsx @@ -0,0 +1,31 @@ +import { CID } from 'multiformats' +import { useEffect } from 'react' + +export const IPFSSubpathRedirect = () => { + function extractHashFromBasePath() { + const htmlBase = document.querySelector('base') + if (!htmlBase) return + const cidRegex = /\/ipfs\/(Qm[1-9A-HJ-NP-Za-km-z]{44,}|b[A-Za-z2-7]{58,}|B[A-Z2-7]{58,}|z[1-9A-HJ-NP-Za-km-z]{48,}|F[0-9A-F]{50,})/ + return htmlBase.href.match(cidRegex)?.at(1) + } + + function generateIPFSRedirect() { + const cidFromPath = extractHashFromBasePath() + + if (!cidFromPath) { + console.log('No IPFS subpath detected') + return + } + + const v1CidString = CID.parse(cidFromPath).toV1().toString() + return `${location.protocol}//${v1CidString}.ipfs.${location.host}` + } + + useEffect(() => { + const redirectUrl = generateIPFSRedirect() + if (!redirectUrl) return + window.location.href = redirectUrl + }, [generateIPFSRedirect]) + + return null +} diff --git a/src/pages/App.tsx b/src/pages/App.tsx index 0b0be3539b2..7d58382d708 100644 --- a/src/pages/App.tsx +++ b/src/pages/App.tsx @@ -1,5 +1,6 @@ import ErrorBoundary from 'components/ErrorBoundary' import Loader from 'components/Icons/LoadingSpinner' +import { IPFSSubpathRedirect } from 'components/IPFSSubpathRedirect' import NavBar, { PageTabs } from 'components/NavBar' import { lazy, Suspense, useEffect, useState } from 'react' import { Navigate, Route, Routes, useLocation } from 'react-router-dom' @@ -100,6 +101,7 @@ export default function App() { return ( +