useCreatePost is a React Hook that lets you create a post for a Profile you own.

const { execute, error, isPending } = useCreatePost({ publisher, upload });


Define an upload function that conforms to the signature:

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


Looking for an inspiration?

Check the web-wagmi example in the Lens SDK monorepo. There is an example upload function that uses Bundlr to upload the file to Aerwave.

You can then wire the useCreatePost into your composer component:

import { ContentFocus, CollectPolicyType, ProfileOwnedByMeFragment, ReferencePolicy, useCreatePost } from '@lens-protocol/react';
import { upload } from './upload'

function Composer({ profile }: { profile: ProfileOwnedByMeFragment }) {
  const { execute: create, error, isPending } = useCreatePost({ publisher: profile, upload });

  const onSubmit = async (content: string) => {
    await create({
      contentFocus: ContentFocus.TEXT,
      locale: 'en',
      collect: {
        type: CollectPolicyType.NO_COLLECT
      reference: {
        type: ReferencePolicy.ANYBODY
  // ...

You can then pass the onSubmit handler to your form



Call useCreatePost in the component responsible for submitting the user's input.

function Composer({ profile }) {
  const { execute, error, isPending  } = useCreatePost({ publisher, upload });
  // ...


  • upload the user-defined upload function. Must conform to the (data: unknown) => Promise<string> signature. It receives a JS Object (safe for serialization) and should return the public URL where the JSON file has been saved. The file must be served as Content-Type: application/json. It's the function's responsibility to serialize, upload and return the file URL.
  • publisher this is the author profile of the new post. It must be a profile owned by the authenticated Signer (see useWalletLogin) as it is returned by useActiveProfile or useProfilesOwnedByMe hooks.


Returns an object with:

  • create: a function you can use to initiate the creation of a new post.
  • isPending: a boolean notifying you when the operation is still in progress.
  • error: any error that might occur in normal operating conditions will be returned via this property. Default value null.

execute function

You can use the execute function to initiate the process that leads to a new post.


It accepts a complex object with all the required configurations. The TS definition will help you to know what configuration to provide and when.

  content?: string,
  contentFocus: ContentFocus,
  locale: string,
  collect: CollectPolicy,
  reference: ReferencePolicy

where locale is a subset of the Locale Identifiers specification. See the full specification here.


Pro tip

Use the TypeScript definition to navigate the possible values for each field and subfields. The type definition provided will guide you through the dependency rules of the Lens Publication Metadata v2 so you don't have to know them.


It returns a Promise<void> that you can use to sync with the state of your component. For example you can clear the content of any text input field when such promise resolves.