Display custom data for each company or person in each thread. Display things like their pricing tier, usage, an impersonation button, activation milestones and more to enable an excellent and fast support experience for your customers.
How to
In your Custom Data settings you specify the endpoint that returns the JSON data of your components. This handler also takes care of fetching and parsing data to be represented. You can also provide headers optionally when creating a Custom Data.
The specified endpoint can handle complex data and integrate multiple data sources. In the end it is important that it returns your customized components structure. The following shows an example using NextJS.
- Create the function that serves the request under e.g.
pages/api/sidebar/section.ts
.
export default async function handler(
req: NextApiRequest,
res: NextApiResponse
) {
return res.status(200).json({
components: [
... // Components structure
]
})
}
- Integrate data sources and fetch all data you want e.g. Stripe, Prisma, etc.
export default async function handler(
req: NextApiRequest,
res: NextApiResponse
) {
// Use email
const email = (req.body as { email: string; threadId: string }).email;
// Fetch for customer data
const customer = await prisma.customer.findUnique({
where: {
email,
},
});
// Get subscription from customer
const { items } = await stripe.subscriptions.retrieve(
customer.subscriptionId
);
// Take priceId from first subscription
const priceId = items.data[0]?.price.id;
return res.status(200).json({
components: [
{
// Components structure
type: "row",
left: [
{
type: "text",
color: "normal",
size: "m",
text: "Current price",
},
],
right: [
{
type: "text",
color: "muted",
size: "s",
text: priceId,
},
],
},
],
});
}
Request Body
The request body contains:
-
threadId: string
-
email: string
Back on the Thread View you will find a new section with the title and the data you are displaying.
Components
We provide you with a set of components including text and button to help you build your custom data integration. Each component needs to be included in a row which is separated by a left and right section for proper vertical and horizontal layout. Choose the attributes you want to apply and add them into a JSON response from your endpoint.
Row
Type | Attributes |
---|
Row | right , left |
Example
{
type: "row",
left: [
{ type: "text", color: "normal", size: "m", text: "Threads created" },
{ type: "text", color: "muted", size: "s", text: "In the last 2 weeks" },
],
right: [{ type: "badge", color: "green", text: "25 of 100" }],
}
Text
Type | Attributes |
---|
Text | color , size , text |
Example
{
type: "text",
color: "normal | muted",
size: "s | m | l",
text: "Threads created"
}
Badge
Type | Attributes |
---|
Badge | color , text |
Example
{
type: "badge",
color: "green",
text: "25 of 100"
}
Spacer
Example
{
type: "spacer",
size: "s | m | l"
}
Type | Attributes |
---|
LinkButton | size , label , url |
Example
{
type: "linkButton",
label: "View usage",
url: "https://google.com"
}
Type | Attributes |
---|
CopyButton | value , tooltip |
Example
{
type: "copyButton",
value: `https://productlane.com/threads/${id}`,
tooltip: "Copy Productlane thread link"
}
Full example
One full example might look like the following. You need to return this structure from your defined webhook/endpoint in order to be rendered as Custom Sidebar Cards.
const components = [
{
type: "row",
left: [
{ type: "text", color: "normal", size: "m", text: "Threads created" },
{ type: "text", color: "muted", size: "s", text: "In the last 2 weeks" },
],
right: [{ type: "badge", color: "green", text: "25 of 100" }],
},
{ type: "spacer", size: "m" },
{
type: "row",
left: [{ type: "text", color: "muted", size: "s", text: "MRR" }],
right: [{ type: "text", color: "normal", size: "m", text: "149" }],
},
{ type: "spacer", size: "m" },
{
type: "row",
left: [{ type: "text", color: "muted", size: "s", text: "ARR" }],
right: [{ type: "text", color: "normal", size: "m", text: "1.788" }],
},
{ type: "spacer", size: "m" },
{ type: "linkButton", label: "View usage", url: "https://google.com" },
];