If you are building a decentralized App, in most cases you need to store your images, files, and videos on a decentralized platform like IPFS, File coin, or Filebase, so in this blog, we will discuss how you can upload your files to File-coin network with the help of Web3. Storage, A tool by File-coin.
Before jumping to code first, let's discuss what is decentralized storage.
So As per the name, Decentralized storage means it is not centralized and all of your data is not stored at some data center that is controlled by a few. In Decentralized storage, users can store their data regardless of center. This system uses a peer-to-peer network model to achieve decentralization.
So let us start our journey to upload files to IPFS using Web3.Storage.
Overview:
Prerequisites:
-A Account on Web3.Storage You can create one for free
-A basic knowledge of JavaScript(of course not mandatory)
So Let's start.
1npx create-react-app filecoin-upload-demo
This will create a basic ReactJS Application for us.
1cd filecoin-upload-demo
Now Open this folder with VS Code For this you can type code .
in terminal or right click and select open with code
At this point your folder structure should look like this:
Now Open the terminal in VS Code by pressing ctrl+shift+`
or Click on Terminal->New terminal
Now in the terminal run the below command
1npm install web3.storage dotenv
This will install web3.storage
js client and dotenv
for loading local environment
Now create a file with the name .env
, In this file, we will keep our token of web3.storage
Now open .env
file and paste the following code
1REACT_APP_WEB3TOKEN=PASTE_YOUR_WEB3STORAGE_TOKEN_HERE
For creating your Token click on Account->Create An API Token
Now click on create an API token and enter the token name demo-upload
and hit enter
You should see your token
Now copy the token by clicking the copy icon next to the token and paste it at .env
file
Now in Terminal run npm run start
, this will start a development server for us
Now open App.js
and delete the default code.
So our project setup is done. Let's start coding
In the App.js
Paste the following code:
1import "./App.css" 2import { Web3Storage } from "web3.storage" 3import { useState } from "react" 4export default function App() { 5 const [file, setFile] = useState(null) 6 const [imageURI, setImageURI] = useState("") 7 const [isUploading, setIsUploading] = useState(false) 8 const client = new Web3Storage({ token: process.env.REACT_APP_TOKEN }) 9 const handleFileChange = (e) => { 10 e.preventDefault() 11 if (e.target.files[0]) { 12 setFile(e.target.files[0]) 13 } 14 } 15 const uploadFile = async () => { 16 setIsUploading(true) 17 const fileToUpload = new File([file], file.name.split(" ").join(""), { 18 type: file.type, 19 }) 20 const cid = await client.put([fileToUpload], { 21 name: file.name, 22 }) 23 setImageURI( 24 `https://${cid}.ipfs.w3s.link/${file.name.split(" ").join("")}` 25 ) 26 setFile(null) 27 setIsUploading(false) 28 } 29 30 return ( 31 <div className="container"> 32 <h1 className="title">Upload files with Web3.Storage</h1> 33 {isUploading && <div className="uploading">Uploading file...</div>} 34 <input 35 className="input" 36 type={"file"} 37 onChange={handleFileChange} 38 /> 39 {file && ( 40 <button className="upload" onClick={uploadFile}> 41 Upload File 42 </button> 43 )} 44 {imageURI.length > 0 && ( 45 <div className="link"> 46 <a href={imageURI}>Go To Your File</a> 47 {imageURI} 48 </div> 49 )} 50 </div> 51 ) 52}
Let's understand the code line by line
1import "./App.css" 2import { Web3Storage } from "web3.storage" 3import { useState } from "react"
Here We are importing Our CSS File, Web3Storage module, and useState hook.
export default function App(){
is exporting a React Component with the name App Inside of this, Our entire code is wrapped
1 const [file, setFile] = useState(null) 2 const [imageURI, setImageURI] = useState("") 3 const [isUploading, setIsUploading] = useState(false)
Here we are declaring three states
file: To keep track of the file that the user has selected
imageURI: When the upload is done we will update this state with the Image's URL.
isUploading : Of course, we need to show the loader until the file is uploaded, to keep track of this we are having this state and by default the value is false;
Don't get overwhelmed by useState, it's just a hook by React to keep track of variables.
1const handleFileChange = (e) => { 2 e.preventDefault() 3 if (e.target.files[0]) { 4 setFile(e.target.files[0]) 5 } 6 }
This is the function that handles the file selected by the user and this function is called when the user selects any file e.preventDefault()
prevents the page from reloading
if the user has selected any file then the if condition is true and we are updating our file state with the user-selected file.
Now The Main Function which uploads the file to IPFS
Yes it's the uploadFile
function
1const uploadFile = async () => { 2 setIsUploading(true) 3 const client = new Web3Storage({ token: process.env.REACT_APP_TOKEN }) 4 const fileToUpload = new File([file], file.name.split(" ").join(""), { 5 type: file.type, 6 }) 7 const cid = await client.put([fileToUpload], { 8 name: file.name, 9 }) 10 setImageURI( 11 `https://${cid}.ipfs.w3s.link/${file.name.split(" ").join("")}` 12 ) 13 setFile(null) 14 setIsUploading(false) 15 }
So you notice that the function is async
, what does it mean
It simply means that uploading the file can take some time and we want to code execute one by one
As soon as the function is called, We are setting the upload state to true it will display the loader.
After that, we are initializing Web3.Storage class by const client=new Web3Storage({token:REACT_APP_TOKEN})
Web3.Storage needs our token for verification, So we are providing the token by process.env.REACT_APP_TOKEN
It will simply load the environment Variable from our .env
file to our Site
After that, we are preparing our file for Upload by
1const fileToUpload = new File([file], file.name.split(" ").join(""), { 2 type: file.type, 3 })
This will create a new File in the browser environment by invoking the File Class
It takes the blob, the name of the file, and the file type
Now our file is ready for upload,
1 const cid = await client.put([fileToUpload], { 2 name: file.name, 3 })
This will call the client.put method and it takes our file and name as an argument and returns the file hash
By using await
we are waiting for the upload to be done.
Hooray 🎉 🎉🥳 Our file has been uploaded to IPFS
Wait wait wait What about giving the file URL to the user.
After that, we are setting our imageURI state, then we will clear the file state and disable the loader
1setImageURI( 2 `https://${cid}.ipfs.w3s.link/${file.name.split(" ").join("")}` 3 ) 4 setFile(null) 5 setIsUploading(false)
Now if you go to localhost
You should see the screen like this :
Still, Its looks like an old-age site, Let's add some CSS to it.
Now Open your App.css
and Paste the following code
1.container { 2 min-height: 100vh; 3 background-color: #2c2c2c; 4 display: flex; 5 flex-direction: column; 6 align-items: center; 7 justify-content: space-around; 8} 9.title { 10 color: aqua; 11} 12.input::-webkit-file-upload-button { 13 background-color: orchid; 14 padding: 10px; 15 outline: none; 16 border: none; 17 color: aliceblue; 18 border-radius: 5px; 19 font-size: 1.5rem; 20} 21.upload { 22 background-color: blueviolet; 23 padding: 10px; 24 outline: none; 25 border: none; 26 color: aliceblue; 27 border-radius: 5px; 28 font-size: 1.5rem; 29} 30a { 31 color: aquamarine; 32} 33.link { 34 display: flex; 35 flex-direction: column; 36 justify-content: center; 37 align-items: center; 38 color: aquamarine; 39 font-size: 1.4rem; 40} 41.uploading { 42 color: orchid; 43 font-size: 1.2rem; 44 animation: upload 1.2s ease-in-out infinite; 45} 46@keyframes upload { 47 0% { 48 font-size: 1.2rem; 49 opacity: 1; 50 } 51 50% { 52 font-size: 1.5rem; 53 opacity: 0.5; 54 } 55 100% { 56 font-size: 1.2rem; 57 opacity: 1; 58 } 59}
Now our page should look like this
Now Click on Choose file, Select the file you want to upload, and Press upload file button
After 1s or 2s you should see the link to your file which is now uploaded on IPFS.
So, if you followed until here,have a big clap for yourself
Until next, Keep coding, Keep Hustling
Feel free to contact me :