Velenir/nextjs-ipfs-example

Error on non default url

cardimajs opened this issue · 2 comments

Hi, tank you for this demo.

i followed all steps,

when i go to this url https://ipfs.io/ipfs/QmZ3DrJsv4SZnfPVC3vhbtGYYk9AbkU8ooFjE92LW6M5Dy/
every works, but when i try to go to a custom url like /contact
https://ipfs.io/ipfs/QmZ3DrJsv4SZnfPVC3vhbtGYYk9AbkU8ooFjE92LW6M5Dy/contact/

works, but i get an error on console

image

can you help me to fix this error?

tank you.

Hello, cardimajs!

So what happens here is that when you access your site, whether at root path or /contact/ path, you first get an html file:

<!DOCTYPE html>
<html lang="en">
<head>
<script>
--
  | (function () {
  | const { pathname } = window.location
  | const ipfsMatch = /.*\/Qm\w{44}\//.exec(pathname)
  | const base = document.createElement('base')
  | base.href = ipfsMatch ? ipfsMatch[0] : '/'
  | document.head.append(base)
  | })();
  | 
</script>
<meta name="theme-color" content="#556cd6"/>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700&amp;display=swap"/>
<meta charSet="utf-8"/>
<meta name="viewport" content="minimum-scale=1, initial-scale=1, width=device-width"/>
<title>Contact</title><meta name="next-head-count" content="3"/>
<link rel="preload" href="./_next/static/SUcle81b5sO2h1xLfCFoW/pages/contact.js" as="script"/>

// etc., etc.

You can check that by inspecting page source or the very first response in Network tab in DevTools.

After the browser gets that html code, it starts downloading whatever resources are linked there.
Absolute uri resources (like google fonts) are resolved without problem.
Relative resource (e.g. ./_next/static/SUcle81b5sO2h1xLfCFoW/pages/contact.js) are resolved relatively to document.baseURI (document.baseURI + relative_uri). When <base href> isn't explicitly set, document.baseURI = location.origin + location.pathname:

  • for root path https://ipfs.io/ipfs/QmZ3DrJsv4SZnfPVC3vhbtGYYk9AbkU8ooFjE92LW6M5Dy/ that would be https://ipfs.io/ipfs/QmZ3DrJsv4SZnfPVC3vhbtGYYk9AbkU8ooFjE92LW6M5Dy/_next/static/SUcle81b5sO2h1xLfCFoW/pages/contact.js, which is the correct location => fetch succeeds
  • for any non-root path, eg. https://ipfs.io/ipfs/QmZ3DrJsv4SZnfPVC3vhbtGYYk9AbkU8ooFjE92LW6M5Dy/contact/ that would be https://ipfs.io/ipfs/QmZ3DrJsv4SZnfPVC3vhbtGYYk9AbkU8ooFjE92LW6M5Dy/contact/_next/static/SUcle81b5sO2h1xLfCFoW/pages/contact.js, which is incorrect => fetch fails

To be able to dynamically change uri resolution according to arbitrary Qm<hash>, we add a <base href="/ipfs/QmZ3DrJsv4SZnfPVC3vhbtGYYk9AbkU8ooFjE92LW6M5Dy/"> element

Now document.baseURI = location.origin +/ipfs/QmZ3DrJsv4SZnfPVC3vhbtGYYk9AbkU8ooFjE92LW6M5Dy/ == https://ipfs.io/ipfs/QmZ3DrJsv4SZnfPVC3vhbtGYYk9AbkU8ooFjE92LW6M5Dy/
Browser detects a document.baseURI change and retries relatively linked resources:

You can see the whole process of try -> fail -> retry -> succeed in the Network tab of DevTools
Unfortunately as we can't have the correct base.href statically, on the page load, we can't skip failing requests.
Though theoretically, we could set up a service worker that would know to redirect such requests to correct paths.

To sum it up -- have to live with the errors.

Thank you for your time and awesome answer