React
docsly is a React (opens in a new tab) component built in Typescript that integrates with any React application using the React version >17. We chose React for it's simplicity and vast adoption (other than the fact that we love it so dearly ❤️).
docsly comes with first-class support for popular documentation frameworks based in React:
React 18 and RSC
docsly is a client only component. You must use the "use client"
directive in your React 18 project to use docsly.
Installation
To install docsly in your project, run the installation command using your favourite package manager:
pnpm add @docsly/react
# or
yarn add @docsly/react
# or
npm install @docsly/react
Props
docsly takes in the following props:
Name | Type | Description | Required |
---|---|---|---|
publicId | string | The public ID of the docsly project copied from the dashboard. | true |
pathname | string | The pathname of the current page. | true |
onDocslyEvent | (string, object | boolean) => void | Recieve docsly events such as feedback or comment. | false |
getUserToken | () => Promise<string> | **Recommended** Returns a `JWT` token representing the authenticated User. | false |
appearance | Appearance | Appearance customization using `className` for different docsly elements. | false |
user | User | The user object representing the documentation reader. | false |
highlightToComment | boolean | Allow users to highlight text to start comment. | false |
showCommentAvatar | boolean | Show the user's avatar where the comment was left. You'd mostly use this with public mode. | false |
showHighlightedText | boolean | Show highlighted text for comments. You'd mostly use this with public mode. | false |
publicId
The publicId
is your project's unique identifier. You can find it in the dashboard (opens in a new tab) under the project settings.
You must create a new project and use it's publicId
when deploying your
project to avoid misuse of the development project's private ID.
pathname
The pathname
prop is the current page's pathname. This is used to identify the current page to map the feedback correctly.
We require the pathname
as a prop to keep docsly unopinionated. This way you can use routing solution of your choice such as the useLocation
hook from react-router
or next/router
to get the pathname.
onDocslyEvent
The callback function onDocslyEvent
is called when a user leaves a feedback or comment. It's useful when you want to use these events for analytics tools such as PostHog or Google Analytics.
onDocslyEvent: (
event: "docsly_comment" | "docsly_reply" | "docsly_feedback",
value: {text: string, metadata?: object, threadId?: string} | boolean
) => void;
getUserToken
The getUserToken
prop is beneficial for auth enabled documentation websites. It allows you to pass in a function that returns a JWT
token representing the authenticated User instead of sharing the raw User object.
To use this option, you must add a JWKS (JSON Web Key Sets) endpoint to your docsly project settings from the dashboard. This endpoint is used to verify the token using your public key. Every auth provider has a JWKS endpoint, which you can get from your auth provider's dashboard. To learn more about JWKS endpoint, see JSON Web Key Sets (opens in a new tab)
The getUserToken
prop takes precedence over the user
prop. If you provide both, getUserToken
is used.
Your JWT template must contain the following claims:
Claim | Usage |
---|---|
sub | The user's unique identifier. |
name | The user's name. |
email | The user's email. |
picture | The URL to the user's profile picture. |
To learn more about JWT claims, see JSON Web Token Claims (opens in a new tab).
For projects without a jwks
endpoint, the getUserToken
prop is ignored and
the User object is set anonymous.
In the following example, we use @clerk/next
as our auth provider and retrive the JWT
token using their getToken
helper.
"use client";
import "@docsly/react/dist/index.css";
import { usePathname } from "next/navigation";
import { useAuth } from "@clerk/nextjs";
import Docsly from "@docsly/react";
export default function DocslyClient() {
const pathname = usePathname();
const { getToken } = useAuth();
const getUserToken = async () => {
const token = await getToken({ template: "docsly" });
if (!token) return "";
return token;
};
return (
<Docsly
publicId="<copy-from-dashboard>"
pathname={pathname}
getUserToken={getUserToken}
/>
);
}
user
The user
prop is beneficial for auth enabled documentation websites. It allows you to pass in the user object to docsly to identify the user and help with collaborating with them.
type User {
name?: string; // user name
sub?: string; // user id
email?: string; // user email
picture?: string; // URL to user's profile picture
};
appearance
The appearance
prop lets you customize docsly elements to suit your documentation design.
export type DocslyAppearance = {
docslyTextHighlightStyles?: string;
docslyBrandStyles?: string;
docslyToolboxStyles?: string;
docslyInboxStyles?: string;
docslyCommentBoxStyles?: string;
docslyInputStyles?: string;
};
You can assign a className
to each of the above props to customize the appearance of that docsly elements.
You can also use a CSS Module identifier to customize the appearance of the docsly elements. To learn more about using CSS Modules in React, see adding css modules (opens in a new tab).
By default, docsly uses TailwindCSS classNames and the default values for appearance
are:
const defaultAppearance = {
docslyTextHighlightStyles: "dy-opacity-50 dy-bg-[hotpink]",
docslyBrandStyles: "dy-bg-[#005BE4] dy-text-neutral-50",
docslyToolboxStyles: "dy-bg-black dy-text-neutral-100",
docslyInboxStyles: "dy-bg-black dy-text-neutral-100 dy-border-neutral-800",
docslyCommentBoxStyles:
"dy-border-neutral-300 dy-bg-black dy-text-neutral-200",
docslyInputStyles: "dy-bg-inherit placeholder:dy-text-neutral-400",
};
Customization
Although we love the default (dark) theme of docsly elements, you might want to customize it according to your brand's design guidelines.
Finding docsly elements
Every customizable docsly element has a corresponding class
in the appearance
prop. To find the class
of a docsly element,
you can use the browser's inspect element feature. For example, in the following screenshot we're inspecting the
docsly toolbox element and we can see that it has a class
of docslyToolboxStyles
.
To customize your docsly component, you can do follow one of approaches listed below:
We recommend only customizing the background-color
, color
, border-color
, and opacity
of the docsly elements to keep the design consistent.
Using TailwindCSS
docsly elements are built using TailwindCSS with a dy
prefix to avoid name collisions.
You can customize the appearance of the docsly elements by overriding the TailwindCSS classes.
For example, to change the background color of the docsly toolbox element to orange
, you can add the following appearance
prop:
"use client";
import Docsly from "@docsly/react";
import "@docsly/react/styles.css";
import { usePathname } from "next/navigation";
export default function DocslyClient() {
const pathname = usePathname();
if (pathname.startsWith("/docs")) {
return (
<Docsly
publicId={process.env.NEXT_PUBLIC_DOCSLY_PUBLIC_ID}
pathname={pathname}
appearance={{
docslyToolboxStyles: "bg-orange-600 text-orange-50",
}}
/>
);
}
return null;
}
Customized docsly toolbox:
Using CSS Modules
You can also use CSS Modules to customize the appearance of the docsly elements.
To do so, create a new docsly.module.css
file and add the following styles:
.docslyToolboxStyles {
background-color: orange;
color: white;
}
Then inside your DocslyClient
component, import the docsly.module.css
file
and pass the docslyToolboxStyles
class to the appearance
prop:
"use client";
import Docsly from "@docsly/react";
import "@docsly/react/styles.css";
import { usePathname } from "next/navigation";
import styles from "./docsly.module.css";
export default function DocslyClient() {
const pathname = usePathname();
if (pathname.startsWith("/docs")) {
return (
<Docsly
publicId={process.env.NEXT_PUBLIC_DOCSLY_PUBLIC_ID}
pathname={pathname}
appearance={{
docslyToolboxStyles: styles.docslyToolboxStyles,
}}
/>
);
}
return null;
}