Fügen Sie Ihren Dokumenten mit Markdoc, Next.js und PropelAuth personalisierte Inhalte hinzu

Vor einigen Tagen hat Stripe Markdoc als Open Source bereitgestellt, ein Markdown-basiertes Authoring-Framework. Es wird verwendet, um die Dokumente von Stripe mit Strom zu versorgen, was bereits ein wirklich starkes Verkaufsargument ist, aber eines der ersten Dinge, die mir aufgefallen sind, war Folgendes:

// markdoc/tags.js

import { Button } from '../components/Button';

export const button = {
  render: Button,
};
[//]: <> (pages/docs/example.md)

We can easily add React components to our markdown files:
{% button %}Button Text{% /button %}

(basierend auf diesem Beispiel) Sie können Ihre eigenen React-Komponenten erstellen und sie dann ganz einfach in Ihre Markdown-Dateien einfügen. Sehen wir uns einige interessante Möglichkeiten an, wie wir dies verwenden können:

React-Hooks verwenden

Wir können beginnen, indem wir die aktuelle Uhrzeit anzeigen und useEffect verwenden um es auf dem neuesten Stand zu halten. Befolgen Sie zunächst die Anweisungen zum Einrichten eines neuen Projekts mit Next.js oder React. In meinem Fall habe ich Next.js verwendet.

Dann können wir unsere Komponente erstellen:

import {useEffect, useState} from "react";

const DateComponent = () => {
    const [date, setDate] = useState(new Date())

    // Update the date every second
    useEffect(() => {
        const timer = setInterval(() => {
            setDate(new Date())
        }, 1000)

        // Clear the timer when we unmount
        return () => { clearInterval(timer) }
    }, [])

    return <div>{date.toLocaleString()}</div>
}

export default DateComponent

Danach in markdoc/tags.js , exportieren wir ein Tag namens date die auf unseren DateComponent verweist

import DateComponent from "../components/DateComponent";

export const date = {
    render: DateComponent,
};

Und schließlich können wir eine Markdown-Datei (pages/docs/date-example.md ) und verwenden Sie das Datums-Tag:

# Date tag:

{% date /%}

Ziemlich einfach! Wenn Sie einen praktischeren Anwendungsfall wünschen, können Sie so etwas wie das Anzeigen des Alters des Beitrags mit humanize-duration tun.

Hinzufügen eines API-Schlüssels zu Ihrer Dokumentation

Wir können schicker werden. Da unsere Komponente wirklich alles kann, was wir wollen, können wir Informationen abrufen und direkt in unseren Dokumenten anzeigen.

Ein nettes Feature, das die Dokumentation zu den Entwicklertools oft hat, ist der Live-API-Schlüssel des Benutzers, der in die Dokumentation eingebettet ist, wenn er angemeldet ist.

Dazu können wir damit beginnen, dass wir einfach einen Abruf zu einer Next.js-API-Route durchführen, die wir erstellen werden:

import {useEffect, useState} from "react";

const ApiKey = () => {
    const [apiKey, setApiKey] = useState(null)

    useEffect(() => {
        fetchApiKey(accessToken).then(setApiKey)
    }, [])

    if (apiKey) {
        return <pre className="apiKey">{apiKey}</pre>
    } else {
        return <pre className="apiKey"><Loading/></pre>
    }
}

function fetchApiKey() {
    return fetch("/api/apikey", {
        method: "GET",
    }).then(res => res.text())

}

export default ApiKey

Dies ist jedoch nicht ganz sinnvoll, da wir keine Benutzerinformationen hinzugefügt haben, sodass wir nicht wissen, wessen API-Schlüssel abgerufen werden soll. Wir können PropelAuth verwenden, um dies schnell in ein authentifiziertes umzuwandeln entweder für einen Benutzer anfordern:

import {useAuthInfo, useRedirectFunctions} from "@propelauth/react";
import {useEffect, useState} from "react";

const ApiKey = () => {
    const {loading, isLoggedIn, accessToken} = useAuthInfo()
    const {redirectToLoginPage} = useRedirectFunctions()
    const [apiKey, setApiKey] = useState(null)

    // Check to see if they are logged in before we fetch
    useEffect(() => {
        if (accessToken) {
            fetchApiKey(accessToken).then(setApiKey)
        } else {
            setApiKey(null)
        }
    }, [accessToken])

    // New state: if they aren't logged in display a link
    //   to PropelAuth's hosted login screen so they can login
    if (apiKey) {
        return <pre className="apiKey">{apiKey}</pre>
    } else if (!loading && !isLoggedIn) {
        return <pre className="apiKey">
              <a href="#" onClick={redirectToLoginPage}>Login</a> to view your API key
          </pre>
    } else {
        return <pre className="apiKey"><Loading/></pre>
    }
}

// fetchApiKey now takes in an accessToken and passes it in the header
function fetchApiKey(accessToken) {
    return fetch("/api/apikey", {
        method: "GET",
        headers: {"Authorization": `Bearer ${accessToken}`}
    }).then(res => res.text())

}

export default ApiKey

oder für eine Organisation, bei der der Benutzer Mitglied ist:

const {loading, isLoggedIn, accessToken, orgHelper} = useAuthInfo()

useEffect(() => {
    if (accessToken) {
        // Get the API key for an organization that the user is a member of
        const orgId = orgHelper.getSelectedOrg()
        fetchApiKey(orgId, accessToken).then(setApiKey)
    } else {
        setApiKey(null)
    }
}, [accessToken])

Die API-Route, die wir erstellen, um diese Anwendungsfälle zu unterstützen, sieht folgendermaßen aus:

export default async function handler(req, res) {
    // Verifies that a valid accessToken is provided
    await requireUser(req, res);

    // req.user comes from requireUser
    const apiKey = await fetchApiKeyFromSecretManager(req.user.userId);
    res.status(200).send(apiKey)
}

und Sie können entweder unserem Next.js-Leitfaden oder unserer Dokumentation folgen, um mehr zu erfahren und es für Ihren Anwendungsfall anzupassen.

Genau wie der date -Tag müssen wir es zu markdoc/tags.js hinzufügen , und erstellen Sie eine Markdown-Datei, um Folgendes zu erstellen:

Zusammenfassung

Die Möglichkeit, schnell und einfach beliebige React-Komponenten zu einer Markdown-Datei hinzuzufügen, ist wirklich cool! Es ermöglicht Ihnen, wirklich kreativ zu sein und Ihren Markdown-Dateien ganz einfach dynamische Inhalte hinzuzufügen.