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 Add support for wrapping quick uploads in a directory. · Issue #349 · ipfs/ipfs-companion · GitHub 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