Markdoc, Next.js 및 PropelAuth를 사용하여 개인화된 콘텐츠를 문서에 추가합니다.

며칠 전 Stripe는 마크다운 기반 저작 프레임워크인 오픈소스Markdoc를 공개했습니다. 이미 강력한 판매 포인트인 Stripe의 문서에 전원을 공급하는 데 사용되었지만 내 눈을 사로잡은 첫 번째 항목 중 하나는 다음과 같습니다.

// 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 %}


(this 예제 기반) 나만의 React 구성 요소를 만든 다음 마크다운 파일에 매우 쉽게 추가할 수 있습니다. 이를 사용할 수 있는 몇 가지 흥미로운 방법을 살펴보겠습니다.

반응 후크 사용



현재 시간을 표시하고 useEffect를 사용하여 계속 업데이트하는 것으로 시작할 수 있습니다. Next.js 또는 React 으로 새 프로젝트를 설정하는 지침에 따라 시작합니다. 제 경우에는 Next.js를 사용했습니다.

그런 다음 구성 요소를 만들 수 있습니다.

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


그런 다음 markdoc/tags.js에서 date를 참조하는 DateComponent라는 태그를 내보냅니다.

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

export const date = {
    render: DateComponent,
};


마지막으로 마크다운 파일( pages/docs/date-example.md )을 만들고 날짜 태그를 사용할 수 있습니다.

# Date tag:

{% date /%}




아주 쉽습니다! 좀 더 실용적인 사용 사례를 원한다면 humanize-duration 으로 게시물의 나이를 표시하는 것과 같은 작업을 수행할 수 있습니다.

문서에 API 키 추가



우리는 더 멋질 수 있습니다. 구성 요소는 실제로 원하는 모든 작업을 수행할 수 있으므로 정보를 가져와서 문서에 직접 표시할 수 있습니다.

개발자 도구 문서에 종종 있는 멋진 기능 중 하나는 사용자가 로그인한 경우 문서에 내장된 사용자의 라이브 API 키입니다.



이를 위해 생성할 Next.js API 경로를 가져오는 것으로 시작할 수 있습니다.

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


사용자 정보를 추가하지 않았기 때문에 누구의 API 키를 가져올지 알 수 없기 때문에 이는 말이 되지 않습니다. PropelAuth을 사용하여 사용자에 대한 인증된 요청으로 빠르게 전환할 수 있습니다.

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


또는 사용자가 속한 조직의 경우:

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])


이러한 사용 사례를 지원하기 위해 생성할 API 경로는 다음과 같습니다.

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)
}


당사Next.js guide 또는 당사documentation를 팔로우하여 자세한 내용을 알아보고 사용 사례에 맞게 사용자 지정할 수 있습니다.
date 태그와 마찬가지로 markdoc/tags.js 에 추가하고 마크다운 파일을 생성해야 합니다.



요약



Markdown 파일에 임의의 React 구성 요소를 빠르고 쉽게 추가하는 기능은 정말 멋집니다! 이를 통해 정말 창의적이고 마크다운 파일에 동적 콘텐츠를 쉽게 추가할 수 있습니다.

좋은 웹페이지 즐겨찾기