What we're going to build
In this guide we'll setup a Docusaurus site for our docs and start collecting feedback from our readers using DocLabs.
You can also check out a live demo here.
Create your Docusaurus site
First, let's setup a basic docs website. Here we're using the basic theme but the steps that follow will work for more complex docs which use i18n and versioning.
npx create-docusaurus@latest <name> classic
Create your DocLabs site
DocLabs is an analytics platform and feedback toolkit specifically for documentation. It focuses on simplicity, privacy and customisability while still being incredibly powerful. It allows maintainers to gather more than just usage data with deep insights, and improve the docs with AI-powered suggestions.
Sign up here to get access.
New site and allowed origins
Create a new site through the dashboard and copy your site ID. Next, navigate to your site settings and configure the allowed origins. We'll start by adding http://localhost:3000
for development and testing but remember to also add your production URL too.
Install the headless components
DocLabs ships with headless UI components for collecting user feedback including likes, ratings and comments. These components can be mixed and matched to build whatever feedback flow you want.
npm install @doclabs/react
Swizzle the footer
To add our own components to the doc page footer we need to swizzle the component:
npm run swizzle @docusaurus/theme-classic DocItem/Footer -- --eject
Finally add our DocLabs components and make them pretty:
// src/theme/DocItem/Footer/index.js
import React from "react";
import clsx from "clsx";
import { ThemeClassNames } from "@docusaurus/theme-common";
import { useDoc } from "@docusaurus/theme-common/internal";
import LastUpdated from "@theme/LastUpdated";
import EditThisPage from "@theme/EditThisPage";
import TagsListInline from "@theme/TagsListInline";
import styles from "./styles.module.css";
import {
Provider as DoclabsProvider,
LikeButton,
DislikeButton,
} from "@doclabs/react";
function TagsRow(props) {
return (
<div
className={clsx(
ThemeClassNames.docs.docFooterTagsRow,
"row margin-bottom--sm"
)}
>
<div className="col">
<TagsListInline {...props} />
</div>
</div>
);
}
function EditMetaRow({
editUrl,
lastUpdatedAt,
lastUpdatedBy,
formattedLastUpdatedAt,
}) {
return (
<div className={clsx(ThemeClassNames.docs.docFooterEditMetaRow, "row")}>
<div className="col">{editUrl && <EditThisPage editUrl={editUrl} />}</div>
<div className={clsx("col", styles.lastUpdated)}>
{(lastUpdatedAt || lastUpdatedBy) && (
<LastUpdated
lastUpdatedAt={lastUpdatedAt}
formattedLastUpdatedAt={formattedLastUpdatedAt}
lastUpdatedBy={lastUpdatedBy}
/>
)}
</div>
</div>
);
}
export default function DocItemFooter() {
const [feedbackSubmitted, setFeedbackSubmitted] = React.useState(false);
const handleFeedbackSuccess = React.useCallback(() => {
setFeedbackSubmitted(true);
}, []);
const { metadata } = useDoc();
const {
editUrl,
lastUpdatedAt,
formattedLastUpdatedAt,
lastUpdatedBy,
tags,
} = metadata;
const canDisplayTagsRow = tags.length > 0;
const canDisplayEditMetaRow = !!(editUrl || lastUpdatedAt || lastUpdatedBy);
const canDisplayFooter = canDisplayTagsRow || canDisplayEditMetaRow;
if (!canDisplayFooter) {
return null;
}
return (
<footer
className={clsx(ThemeClassNames.docs.docFooter, "docusaurus-mt-lg")}
>
<DoclabsProvider
siteId="YOUR ID HERE"
identifier={{
lvl1: metadata.id,
lvl2: "docs",
}}
>
<div className={styles.doclabs}>
{feedbackSubmitted ? (
<div className={styles.doclabsLabel}>Thanks for the feedback!</div>
) : (
<>
<div className={styles.doclabsLabel}>Was this helpful?</div>
<div className={styles.doclabsButtons}>
<LikeButton
onSuccess={handleFeedbackSuccess}
className={styles.doclabsButton}
>
😊
</LikeButton>
<DislikeButton
onSuccess={handleFeedbackSuccess}
className={styles.doclabsButton}
>
😔
</DislikeButton>
</div>
</>
)}
</div>
</DoclabsProvider>
{canDisplayTagsRow && <TagsRow tags={tags} />}
{canDisplayEditMetaRow && (
<EditMetaRow
editUrl={editUrl}
lastUpdatedAt={lastUpdatedAt}
lastUpdatedBy={lastUpdatedBy}
formattedLastUpdatedAt={formattedLastUpdatedAt}
/>
)}
</footer>
);
}
/* src/theme/DocItem/Footer/styles.module.css */
.lastUpdated {
margin-top: 0.2rem;
font-style: italic;
font-size: smaller;
}
@media (min-width: 997px) {
.lastUpdated {
text-align: right;
}
}
.doclabs {
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
gap: 1rem;
margin-bottom: 3rem;
}
.doclabsLabel {
font-size: 1.2rem;
font-weight: 600;
}
.doclabsButtons {
display: flex;
flex-direction: row;
align-items: center;
gap: 0.1rem;
}
.doclabsButton {
border: 0;
outline: none;
background: none;
cursor: pointer;
font-size: 2rem;
}
Don't forget to add your site ID. Also notice how the identifier is fully configurable. This is where you can add metadata that you want to filter on such as language or version.
Deploy your site and sit back and watch the feedback roll in through the dashboard.
Wrap up
DocLabs is building the best platform for documentation feedback. If you're interested in using it yourself you can sign up here.