Mentions
This guide will show you how mentions work on Lens.
Mentions are tracked by the Lens API when included in the content field of the Post metadata.
Example
import { textOnly } from "@lens-protocol/metadata";
const metadata = textOnly({ content: `Hey @lens/stani, how are you?`,});
Lens supports two types of mentions: Account and Group mentions.
Account Mentions
In Lens, an Account can have multiple usernames, but only one username per Username Namespace.
Global Lens Namespace
A special case is the global Lens Username namespace (i.e., lens/). In this case, account mentions take the familiar form:
@lens/<local_name>
where <local_name> is the Lens Account's name under the global Lens Username namespace.
For example:
Hey @lens/stani, how are you?
Custom Namespaces
The general format for a mention is:
@<namespace_address>/<account_address>
where:
<namespace_address>: The address of the Username namespace contract associated with the account.
<account_address>: The address of the Lens Account being mentioned.
For example:
Hey @0x123abc456…/0x789def123…, how are you?
0x123abc456… is the Username namespace contract address.
0x789def123… is the mentioned Lens Account address.
Group Mentions
Group mentions are similar to Account mentions, but with a different format:
#<group_address>
where <group_address> is the address of the Group being mentioned.
For example:
To all #0x123abc456… members, please check the latest update.
Rendering Mentions
Use the post.mentions field to replace raw mentions in the Post content with a more user-friendly format.
Below a more detailed example with React.
Define components for group and account mentions.
mentions.tsx
import React from "react";
export function AccountMention({ children, address }: MentionProps) { return <a href={`/account/${address}`}>{children}</a>;}
export function GroupMention({ children, address }: MentionProps) { return <a href={`/group/${address}`}>{children}</a>;}
type MentionProps = { children: React.ReactNode; account: string;};
Replace mentions in the Post content with the corresponding mention component.
This example use markdown-to-jsx to render the Post content, but you can use any other library or custom renderer.
Adding Mentions
It's app responsibility to aid users in selecting the correct Account and format mentions correctly in the Post's metadata content.
Account Mentions
When the user types @ followed by a character, the app should open a lookup interface to help the user select the desired Account.
Hey @stan
- GraphQL
- React
- TypeScript
Use the accounts query to search for Accounts that have a Username matching the search term under the specified namespace.
Make sure to use the BEST_MATCH order for the orderBy field to ensure the most relevant results are returned.
In case of multiple namespaces, you can alias the username field to get an account's username under a specific namespace. It's your app's responsibility to determine which username to display to the user.
Let's say the previous step returned the following accounts:
On user's selection, use the provided data to render a user-friendly mention. For example you can use the username.value like so:
Hey @<selected.username.value>
Finally, when submitting the post, include the mention in the Post's metadata content field according to the specification above.
For the global Lens Username namespace, the mention format remains unchanged:
Example
import { textOnly } from "@lens-protocol/metadata";
const metadata = textOnly({ content: `Hey @${selected.username.value}, how are you?`,});
For custom Username namespaces, include the namespace and account addresses as specified:
Example
import { textOnly } from "@lens-protocol/metadata";
const metadata = textOnly({ content: `Hey @${selected.username1.namespace.address}/${selected.address}, how are you?`,});
That's it—the Lens indexer will track the mention and notify the mentioned Account.
Group Mentions
When the user types # followed by a character, the app should open a lookup interface to help the user select the desired Group.
To all #build
- GraphQL
- React
- TypeScript
Use the groups query to search for Groups that have a name matching the search term.
Query
query { groups(request: { filter: { searchQuery: "build" } }) { items { address metadata { description icon name } } pageInfo { prev next } }}
Let's say the previous step returned the following groups:
Response
{ "data": { "groups": { "items": [ { "address": "0x1234…", "metadata": { "description": "A group for builders", "icon": "https://example.com/icon.png", "name": "Builders" } }, { "address": "0x5678…", "metadata": { "description": "A group for building", "icon": "https://example.com/icon.png", "name": "Building" } } ], "pageInfo": { "prev": null, "next": null } } }}
On user's selection, use the provided data to render a user-friendly mention.
To all #<selected.metadata.name>
Finally, when submitting the post, include the mention in the Post's metadata content field according to the specification above.
Example
import { textOnly } from "@lens-protocol/metadata";
const metadata = textOnly({ content: `To all #${selected.address} members, please check the latest update.`,});
That's it—the Lens indexer will track the mention and populate the post.mentions field with the necessary data.