Adding a file while preserving filename using js-ipfs

Hi, I have a functional app that uses IPFS, it successfully takes a local file via <input type='file'>, turns it into stream, and adds it to IPFS through node.files.add. And it returns the hash, which I can use to retrieve the original file. So for example if I had an image, I could upload it and display it immediately as an <img> tag.

But here’s the problem I’m facing. I am trying to create a download link (<a href>) that links to the ipfs.io gateway so the file can be downloaded through a link. For example I want to upload a PDF file to IPFS and create a gateway link where the file can be downloaded.

But because the gateway url ends with the hash (and not a file extension), whenever I try to download it (or open it in my iOS safari in a new app), it’s not recognized. I’ve looked into all the github issues remotely close to solving this issue, but the closest I’ve found was https://github.com/ipfs-shipyard/ipfs-companion/issues/349 which doesn’t seem to have a solution yet.

If we were just talking about regular web servers, I could just add a file type extension in the end and the browser will know what to do with it, but since all IPFS files (unless they are wrapped in a directory) end with a hash, this is not a feasible solution either.

I know one way to do it manually is to wrap the file in a directory by adding file in the console via add -w option, but couldn’t find a way to do this with JS.

Am I missing something? Or is there currently no way (using JS-IPFS) to upload a file to IPFS and then make it downloadable as a link?

If you want to preserve file name, you need to wrap it in a directory.

Until wrapWithDirectory flag lands in js-ipfs (PR is merged, but not released yet) you can do it manually by adding a named file link to an empty unixfs-dir via object.patch.addLink API.

In command line, it looks like this:

ipfs object patch add-link <root_CID> <file_name> <file_CID> - Add a link to a given object

We know that QmUNLLsPACCz1vLxQVkXqqLX5R1X345qqfHbsf67hvA3Nn is the CIDv0 of an empty dir, so all you really need is one command:

$ ipfs object patch QmUNLLsPACCz1vLxQVkXqqLX5R1X345qqfHbsf67hvA3Nn add-link bug_or_feature.jpg Qmayz4F4UzqcAMitTzU4zCSckDofvxstDuj3y7ajsLLEVs

Example above returns QmVnLkRxWWv2xiPKeQy6re1zCepzX7YXUiq5fESkd1j8bC – a new CID representing a wrapping directory with one file:

https://ipfs.io/ipfs/QmVnLkRxWWv2xiPKeQy6re1zCepzX7YXUiq5fESkd1j8bC/
https://ipfs.io/ipfs/QmVnLkRxWWv2xiPKeQy6re1zCepzX7YXUiq5fESkd1j8bC/bug_or_feature.jpg

JS-IPFS API is here. Hope this helps.

1 Like