Upload Lens metadata

Storing Lens metadata on Irys

In this tutorial, you will learn how to use Irys with the Lens React hooks (opens in a new tab) to upload post metadata.

Lens Protocol is a composable and decentralized social graph; it allows you to quickly create social applications without having to build your own backend services.

React hooks

The React hooks for Lens make client-side development easier as they streamline much of the development, including generating correct metadata for you to upload.

upload() pattern

When working with hooks like useUpdateProfileDetails() (opens in a new tab) and useCreatePost() (opens in a new tab), Lens works using a pattern where you define a function called upload() that matches the following signature.

export const upload = (data: unknown): Promise<string> => {
    const serialized = JSON.stringify(data);
    const url = // upload serialized to a public location
    return url;

The upload() function is passed to the hooks on initialization, the hooks then prepare the required metadata and pass it to upload() in the data parameter. When implementing the function, it's up to you to serialize the metadata (JSON object), store it on Irys and then return the URL from the function. The hook then takes the URL to the uploaded metadata and continues using it to update profile details or create a new post.

A full ready-to-use implementation of the upload() function is as follows:

import { WebIrys } from "@irys/sdk";
import { providers } from "ethers";
const getIrys = async () => {
	await window.ethereum.enable();
	const provider = new providers.Web3Provider(window.ethereum);
	const wallet = { name: "ethersv5", provider: provider };
	const url = "https://node1.irys.xyz";
	const token = "matic";
	const webIrys = new WebIrys({ url, token, wallet });
	await webIrys.ready();
	return webIrys;
export const upload = async (data) => {
	try {
		const irys = await getIrys();
		const serialized = JSON.stringify(data);
		// fund (if needed)
		const price = await irys.getPrice(new Blob([serialized]).size);
		await irys.fund(price);
		const tx = await irys.upload(serialized, {
			tags: [{ name: "Content-Type", value: "application/json" }],
		console.log(`Upload success content URL= https://gateway.irys.xyz/${tx.id}`);
		return `https://gateway.irys.xyz/${tx.id}`;
	} catch (e) {
		console.log("error on upload ", e);
	return "";

If you incorrectly set the Content-Type attribute, Lens will not read your data.