Embedding js-ipfs nodes into websites

Someone suggested that this may in fact be possible, but I don’t know how to check and couldn’t find more information via search engines. My question is about js-ipfs: I would like to know whether it can be embedded within websites themselves, rather than only provided by browser addons such as IPFS Companion.

This is important as I’m thinking of making an IPFS based site. The site itself may be hosted anywhere (Github pages, download and open index.html locally, or even on IPFS itself) but its functionality will require IPFS and the js-ipfs-api interface. For the site to be user friendly, it cannot ask every visitor to install go-ipfs on their computer… and although I could use gateway.ipfs.io that wouldn’t provide essential functionalities like pinning or seeding.

It would be ideal if my site’s index.html file could simply contain a tag that links to the core js-ipfs.js file (from say Github). Once this script is linked, the browser automatically learns how to start a js-ipfs node which will run for as long as a browser tab is open. My own script is spawned after that and uses js-ipfs-api commands to automatically download or add or pin files in the background.

This sounds too easy to be true, but I heard people saying it should be possible. Would such a thing at least work for all Chromium and Firefox users? Are there any limitations or security issues in having web pages spawn js-ipfs nodes in browsers? Thank you.

My question has been answered in this thread. I managed to get a browser node working using the browser example in OrbitDB. I can create and read a database through IPFS flawlessly!

There’s only one minor issue left: What is the URL of the gateway used by the browser node? I tried http://127.0.0.1:8080/ipfs while keeping the browser tab open but there’s nothing at that address. If I want to access a file by its hash, what is the URL I’ll use in this case?

i’m not sure is possible to enable gateway when you use js-ipfs in browser @daviddias exact ?

FYI js-ipfs running in browser is unable to open and listen on new TCP ports, so Gateway feature is unavailable in this context.
Keep in mind that you have access to real IPFS API, so gateway is not really needed – you can read data natively.

1 Like

Oh wow… that is a huge limitation, though I vaguely remember hearing something about that in the past. How do you access files through the node in that case, and obtain an URL through which you can embed them in the HTML page?

Files can be accessed thru IPFS API. A JS example for reading a file can be found in spec for ipfs.files.cat. In short, this is how you add/get raw data. You could add it to your page as data URL, or if you need “a linkable URL”, then you just point at the CID at a public or own HTTP Gateway… In content addressing in won’t matter from which gateway you are fetching the data.

1 Like

Thanks! Figured it would have to be something like a JavaScript function for accessing the files.

I’m a little concerned as to how much you can do with the raw data alone however… namely how you embed a file on a web page. Say I’m accessing a jpg image in my browser node: How do I easily place it inside an <img> element which I generate or modify from the script, without having to point to another IPFS gateway? Thanks.

@MirceaKitsune you can experiment with replacing gateway URLs with inlined data (see DataURL) returned from js-ipfs .

For example, to create <img> element for data fetched from IPFS:

let imgElement = document.createElement('img')
let imgData = await ipfs.cat(`QmbWqxBEKC3P8tqsKc98xmWNzrzDtRLMiMPL8wBuTGsMnR`)
imgElement.src = 'data:image/jpeg;base64,' + imgData.toString('base64')

2 Likes

That is extremely helpful! I shall keep this in mind for when I may attempt this. Thanks!

Hi, @MirceaKitsune

I’m trying to do similar thing + some stuff with pubsub

I’ve managed to run IPFS only website where every client starts to be IPFS node and pins a content related to the website, so as long as someone is online website will become available.

Why I’m trying to achieve now is to load website not from url like:

https://ipfs.io/ipfs/QmRTSA1UFHSx3z7taNRwUVM8AjB2EQwKvyZu3BfJg9QRtZ/home.html

but from url like

https://myowndomain.com

Any idea how to achieve it?
I guess workflow is like that:

  1. Load some static html + javascript that will setup ipfs node in a browser
  2. Fetch data from QmRTSA1UFHSx3z7taNRwUVM8AjB2EQwKvyZu3BfJg9QRtZ
  3. rewrite all urls as it was local

I have problems with step 2 and 3. Have You ever tried something similar?

I haven’t really tried much yet, my ideas are in planning stage. I think what you want is to first put the site on an IPNS domain, then register that domain to a DNS registar (so instead of a hash you have something like somedomain.com). Normally this shouldn’t affect the functionality of js-ipfs… of course as long as you can still point to the hashes of the necessary files.

@adamskrodzki this should be helpful:

@lidel Thank You for help, cloudFlare works for me :slight_smile:

There is an issue I’m still concerned about here: Even if you can get the raw data and put it into an image, won’t some browsers complain about the MIME type and refuse to display the content? I’ve had that issue before: Firefox for instance doesn’t let you reference a text file as a script, it complains that the MIME is “text” and not “script” even if it’s really the same format.

Has this approach been tested and confirmed not to trigger that? Including on Firefox? This includes both loading scripts, embedding images, embedding sound, and embedding video.

To determine the correct content-type you can do mime-sniffing based on a few first bytes using things like file-type.

That being said, if you want to inject a lot of content read from js-ipfs running on a website, doing it via Service Worker may be a better idea: it removes dataURL hack and restores standard HTTP semantics. See demo in the middle of https://js.ipfs.io, basic examples at ipfs/ipfs-service-worker and gateway code at ipfs-shipyard/service-worker-gateway.

1 Like