Analytics & feedback for Docusaurus in 5 mins
Published: 2023-07-06 09:33:02

# 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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2jw27h1d1hzn8jv3mlro.png)

You can also check out a live demo [here](https://docusaurus-example-dusky.vercel.app/docs/intro).

# 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.

```sh
npx create-docusaurus@latest <name> classic
```

# Create your DocLabs site

[DocLabs](https://www.doclabs.dev/) 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](https://tally.so/r/mOlxek) 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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pi1lr5z9lg9j3c3ykgsz.png)

# 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.

```sh
npm install @doclabs/react
```

# Swizzle the footer

To add our own components to the doc page footer we need to _swizzle_ the component:

```sh
npm run swizzle @docusaurus/theme-classic DocItem/Footer -- --eject
```

Finally add our DocLabs components and make them pretty:

```javascript
// 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>
  );
}
```

```css
/* 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.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/m9dmm63uyuj3b9qaflnn.png)

# Wrap up

DocLabs is building the best platform for documentation feedback. If you're interested in using it yourself you can [sign up here](https://tally.so/r/mOlxek).