Uploading Files to IPFS from a Web Application
Tags: javascript, webdev, react, ipfs
Published: 2021-06-28 13:30:46

---
title: Uploading Files to IPFS from a Web Application
published: true
description: How to upload files to IPFS from a web application using IPFS HTTP Client and Infura
tags: javascript, webdev, react, ipfs
---

One of the most common interactions with [IPFS](https://ipfs.io/#how) is uploading files like images and videos from a client-side application, so I found it surprising that there were not a lot of straightforward tutorials showing how this is done.

In this tutorial you will learn just that in as few lines of code (and as simply) as possible using [`ipfs-http-client`](https://github.com/ipfs/js-ipfs/tree/master/packages/ipfs-http-client#readme). The ideas here are implemented in React but should be fairly easily transferrable to doing the same thing in any other JavaScript framework, like Vue, Angular, or Svelte.

## About IPFS

IPFS is a decentralized, peer to peer file sharing protocol. 

There are various types of [IPFS gateways](https://docs.ipfs.io/concepts/ipfs-gateway/#overview) available. Some are free, some are not. Some offer read-only access, and others offer both read and write access.

You can also run [your own IPFS gateway](https://docs.ipfs.io/concepts/ipfs-gateway/#gateway-providers).

Because we will be uploading / saving files, we need to be sure to choose a gateway that allows us write access. The gateway we will be using today is [Infura](https://infura.io/docs/ipfs). Other popular services are [Pinata](https://pinata.cloud/) or [Fleek](https://fleek.co/).

> For this example to work, you need to sign up with [Infura](https://app.infura.io/) and get a project ID and API secret.

For an example of how to pin a file to IPFS with Pinata, check out [this repo](https://github.com/dabit3/ipfs-pinata-example).

## Getting started

> If you already have a React application created, you can skip this step.

First, create a new React app and change into the new directory:

```sh
npx create-react-app ipfs-example

cd ipfs-example
```

Next, install the `ipfs-http-client` library and `buffer` using either __NPM__ or __Yarn__:

```sh
npm install ipfs-http-client buffer
```

## Base code

The basic functionality can be summed up in these lines of code, but I'll also be building out an entire UI to show how it all fits together.

The basic code for getting this to work is here:

```javascript
/* import the ipfs-http-client and buffer libraries */
import { create } from 'ipfs-http-client'
import { Buffer } from 'buffer'

/* configure Infura auth settings */
const projectId = "<your-infura-project-id>"
const projectSecret = "<your-infura-project-secret>"
const auth = 'Basic ' + Buffer.from(projectId + ':' + projectSecret).toString('base64')

/* Create an instance of the client */
const client = create({
  host: 'ipfs.infura.io',
  port: 5001,
  protocol: 'https',
  headers: {
      authorization: auth,
  }
})

/* upload the file */
const added = await client.add(file)

/* or a string */
const added = await client.add('hello world')
```

## Full code

Let's now look at how the above code would be used to actually implement file upload functionality in our app for uploading and viewing images.

In your project, open __src/App.js__ and update it with the following code:

```javascript
/* src/App.js */
import './App.css'
import { useState } from 'react'
import { create } from 'ipfs-http-client'
import { Buffer } from 'buffer'

/* configure Infura auth settings */
const projectId = "<your-infura-project-id>"
const projectSecret = "<your-infura-project-secret>"
const auth = 'Basic ' + Buffer.from(projectId + ':' + projectSecret).toString('base64');

/* create the client */
const client = create({
  host: 'ipfs.infura.io',
  port: 5001,
  protocol: 'https',
  headers: {
      authorization: auth,
  },
})

function App() {
  const [fileUrl, updateFileUrl] = useState(``)
  async function onChange(e) {
    const file = e.target.files[0]
    try {
      const added = await client.add(file)
      const url = `https://infura-ipfs.io/ipfs/${added.path}`
      updateFileUrl(url)
      console.log("IPFS URI: ", url)
    } catch (error) {
      console.log('Error uploading file: ', error)
    }  
  }
  return (
    <div className="App">
      <h1>IPFS Example</h1>
      <input
        type="file"
        onChange={onChange}
      />
      {
        fileUrl && (
          <div>
            <img src={fileUrl} width="600px" />
            <a href={fileUrl} target="_blank">{fileUrl}</a>
          </div>
        )
      }
    </div>
  );
}

export default App
```

Next, run the app:

```sh
npm start
```

When the app loads, you should see a file upload button.

Once a file has been successfully uploaded, you should see it rendered in the UI.