Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ipfs in web apps guide #1970

Draft
wants to merge 4 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .github/styles/pln-ignore.txt
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ mainnet
markdown(lint)
markdownlint
merkle
merklizing
metadata('s)
metamask
minimalistic
Expand All @@ -140,6 +141,7 @@ multiaddrs
multibase
multicast
multicodec
multicodec(s)
multiformats
multihash
multihashes
Expand Down Expand Up @@ -217,6 +219,7 @@ trustlessly
uncensorable
undialable
uniswap
unixfs
unreachability
untrusted
upgradeability
Expand Down
6 changes: 3 additions & 3 deletions docs/.vuepress/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -255,12 +255,12 @@ module.exports = {
]
},
{
title: 'IPFS in the browser',
title: 'IPFS on the web',
sidebarDepth: 1,
collapsable: true,
children: [
'/how-to/ipfs-in-web-apps',
'/how-to/address-ipfs-on-web',
'/how-to/browser-tools-frameworks'
]
},
{
Expand All @@ -277,7 +277,7 @@ module.exports = {
collapsable: true,
children: [
'/how-to/gateway-best-practices',
'/how-to/gateway-troubleshooting'
'/how-to/gateway-troubleshooting',
]
},
{
Expand Down
1 change: 1 addition & 0 deletions docs/.vuepress/redirects
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
/guides/guides/addressing/ /how-to/address-ipfs-on-web
/guides/guides/install/ /install
/how-to/host-single-page-site /how-to/websites-on-ipfs/single-page-website
how-to/browser-tools-frameworks /how-to/ipfs-on-the-web/
/how-to/troubleshoot-file-transfers /how-to/troubleshooting
/how-to/run-ipfs-inside-docker /install/run-ipfs-inside-docker
/install/command-line-quick-start/ /how-to/command-line-quick-start
Expand Down
32 changes: 0 additions & 32 deletions docs/how-to/browser-tools-frameworks.md

This file was deleted.

93 changes: 93 additions & 0 deletions docs/how-to/ipfs-in-web-apps.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
---
title: IPFS in web applications
description: How to develop applications that use IPFS in web browsers, including IPFS retrieval and pinning in browsers using implementations such as Helia.
---

# IPFS in web-applications and resource-constrained environments

This guide covers the key operations of IPFS in the context of web applications, including addressing, retrieving, and providing.

For demonstration purposes, this guide uses [Helia](https://github.com/ipfs/helia), the most actively maintained library for using IPFS on the web and is the recommended library for most use cases.

## Challenges with IPFS on the Web

IPFS allows you to fetch data by CID from multiple providers without being reliant on a single authoritative server.

However, making all of this work on the Web is tricky due to networking constraints. Browsers impose many restrictions on Web apps, for example, opening TCP/UDP connections is not possible. Instead, Web apps are constrained to HTTP, WebSockets, WebRTC, and most recently WebTransport.

There are good reasons for this like security and resource management, but ultimately, it means that using IPFS on the Web is different to native binaries.

## Key IPFS operations: Addressing, Retrieving, and Providing

As a developer, IPFS exposes three main operations for interacting with the network:

- **Addressing data with CIDs** (also known as merkelising): taking arbitrary data and encoding so its addressable by CID. For example, given a file and encoding it so it can be addressed by a CID.

Check failure on line 24 in docs/how-to/ipfs-in-web-apps.md

View workflow job for this annotation

GitHub Actions / pr-content-check

[vale] reported by reviewdog 🐶 [docs.PLNSpelling] Did you really mean 'merkelising'? Raw Output: {"message": "[docs.PLNSpelling] Did you really mean 'merkelising'?", "location": {"path": "docs/how-to/ipfs-in-web-apps.md", "range": {"start": {"line": 24, "column": 48}}}, "severity": "ERROR"}
- **Providing data by CID**: making data addressed by a CID retrievable by other peers, either by running a node or with a pinning service.
- **Retrieving data by CID**: given a CID, IPFS finds providers (peers who share the block), connects to them, fetches the blocks, and verifies.


## Addressing by CID

As mentioned above, the first step in the [lifecycle of data in IPFS](../concepts/lifecycle.md) is to address it by CID.

When addressing data by [CIDs](https://proto.school/anatomy-of-a-cid/03) you will need to choose:

- [hash function](../concepts/glossary.md#hash-function). For use in browsers, the default and recommended hash function is `sha2-256` which is also the default for [helia](https://github.com/ipfs/helia).
- [multicodec](../concepts/glossary.md#multicodec), which is the format of the data you are addressing and is used to help decode data. CIDs support a wide range of multicodecs, but for most intents and purposes, you will likely either want use:

Check failure on line 36 in docs/how-to/ipfs-in-web-apps.md

View workflow job for this annotation

GitHub Actions / pr-content-check

[vale] reported by reviewdog 🐶 [docs.PLNSpelling] Did you really mean 'multicodecs'? Raw Output: {"message": "[docs.PLNSpelling] Did you really mean 'multicodecs'?", "location": {"path": "docs/how-to/ipfs-in-web-apps.md", "range": {"start": {"line": 36, "column": 166}}}, "severity": "ERROR"}
- [unixfs](../concepts/file-systems.md#unix-file-system-unixfs) for files and directories.
- [dag-cbor](../concepts/glossary.md#dag-cbor) for json-like structured data with binary encoding. DAG-CBOR is an extension of CBOR that adds a "link" type for CIDs, allowing for the creation of interlinked CBOR objects (which can be used to form larger linked data structures).

As you can see, there are multiple ways to address data by CID.

One important thing to note is that **the same data can result in different CIDs** depending on a number of factors, including the hash function, the multicodec you use, and the way you encode the data. **This is especially true for files**, where the same file, hash function and multicodec can still result in different CIDs depending on the different options that UnixFS supports. See the [forum discussion](https://discuss.ipfs.tech/t/should-we-profile-cids/18507) for more details and a possible solution.

### Example: Addressing an object by CID with dag-cbor

For example, to address an object by CID with the `dag-cbor` multicodec and `sha2-256` hash function, you can use the following code using [Helia](https://github.com/ipfs/helia):

```ts
import { createHelia } from 'helia'
import { dagCbor } from '@helia/dag-cbor'

const helia = await createHelia()
const d = dagCbor(helia)
const cid = await d.add({ hello: 'world' })

console.info(cid)
// CID(bafyreidykglsfhoixmivffc5uwhcgshx4j465xwqntbmu43nb2dzqwfvae)
```

### Example: Addressing a file by CID with unixfs

<iframe height="500" style="width: 100%;" scrolling="no" title="Addressing an image by CID with Helia and UnixFS" src="https://codepen.io/2color/embed/zxONqPj?default-tab=html%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true">
See the Pen <a href="https://codepen.io/2color/pen/zxONqPj">
Addressing an image by CID with Helia and UnixFS</a> by Daniel Norman (<a href="https://codepen.io/2color">@2color</a>)
</iframe>

## Providing data

In the examples above you saw how to address data by CID. But what you do with it depends on your use case.

If you want to data to be retrievable by other peers on [Mainnet](../concepts/glossary.md#ipfs-mainnet) you will want to upload it to a pinning service or an IPFS node you run.

### You probably don't want to provide data from a browser

Browsers make for lousy servers. It's difficult to make a Web page "dialable", i.e. allow network incoming connections from other computers. There's one exception, namely WebRTC, however, it has many caveats.

For this reason, you should almost never count on providing data from a browser to work.

Instead, you should provide data from a long-running server that runs reliably and has a public IP. That can be a Kubo node that you run, or a [pinning service](../concepts/persistence.md#pinning-services).

### CAR files

CAR files offer a serialized representation of content-addressed resources in one single concatenated stream, alongside a header that describes that content. This makes them a great way to store content-addressed data in a way that is easy to transport and store.


## Retrieval

### With Verified-fetch

<iframe height="500" style="width: 100%;" scrolling="no" title="Fetch an image on IPFS Mainnet @helia/verified-fetch" src="https://codepen.io/2color/embed/QWXKZGx?default-tab=html%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true">
See the Pen <a href="https://codepen.io/2color/pen/QWXKZGx">
Fetch an image on IPFS Mainnet @helia/verified-fetch</a> by Daniel Norman (<a href="https://codepen.io/2color">@2color</a>)
</iframe>
Loading