Analytics & feedback for Docusaurus in 5 mins

Jamie - Jul 6 '23 - - Dev Community

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.

Image description

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
Enter fullscreen mode Exit fullscreen mode

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.

Image description

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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>
  );
}
Enter fullscreen mode Exit fullscreen mode
/* 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;
}
Enter fullscreen mode Exit fullscreen mode

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.

Image description

Wrap up

DocLabs is building the best platform for documentation feedback. If you're interested in using it yourself you can sign up here.

. . . . . . . . . . . . . . . .