JavaScript >> Javascript 文檔 >  >> Node.js

我們如何使用 Notion 作為我們博客的 CMS。

幾個月前,Notion 宣布他們發布了一個公共 API,每個人都可以使用它來使用自己的 Notion 工作區。

我們很感興趣,想看看我們如何從這個新功能中受益。

自從我們開始使用 Rodi 以來,我們一直在努力優化著陸頁。我們仍然相信“Rodi”是我們騎行應用程序的好名字,但我們並不是唯一喜歡這個名字的人,還有其他公司共享這個名字。因此,在 google 上排名靠前並不容易。

改善網站 SEO 的一種方法是添加博客。這讓谷歌有更多關於你正在推廣的產品的背景信息,如果博客文章很好,有些人可能會鏈接回你的網站/博客。

開始

那麼我們給自己設定的要求是什麼

  • 使用直觀的編輯器編寫內容
  • 發布和取消發布文章,不需要對代碼進行任何更改
  • 支持標記和富文本格式(標題、列表、鏈接、代碼塊......)
  • 對 SEO 友好的網址

在閱讀了 Notion api 的文檔後,我們認為 Notion 可以做到這一點,我們就開始工作了。

概念設置

我們需要做的第一件事是創建一個 Notion 數據庫

我們添加了以下列

  • 名稱 - 博客的標題。
  • 狀態 - 未在代碼中使用,但可以方便地跟踪 Notion 中文章的當前狀態。
  • 已發布 - 選中該複選框將立即發布該文章。
  • 簡介 - 對文章內容的簡短描述。
  • Url - 博客的作者可以選擇 url 的 slug 是什麼。 (rodi.app/blog/[網址])

一起破解所有東西

我們的登錄頁面是使用 Next.js 構建的。我不會深入討論代碼的細節,只會介紹一些高級主題。但是通過顯示的代碼片段,您應該能夠了解構建一個由 Notion 驅動的博客需要什麼。如果您想查看所有代碼,可以查看將此博客添加到網站的拉取請求。

您始終可以在 Notion 文檔中找到“入門”和更多詳細信息。

獲取所有發表的文章

首先,我們想要了解所有已發表文章的概覽。

為了能夠從我們的數據庫中獲取項目,我們需要與我們的集成共享我們的數據庫:

完成後,我們可以開始編碼:

export const getBlog = async () => {
  const response = await notion.databases.query({
    database_id: process.env.notion_database_id,
  });

  const published = response.results.filter((blogPost) => {
    return blogPost.properties.Published.checkbox;
  });

  return published;
};

這是我們獲取所有文章並過濾掉尚未發布的文章所需的一切。

獲取文章的內容

因為我們希望能夠根據自定義 url 找到一篇文章。我們需要先獲取所有文章及其屬性。

當我們擁有所有帖子後,我們可以查找與當前 url 匹配的帖子。

現在我們可以使用這篇文章的 id 來獲取頁面的內容。請注意,最多有 100 個塊。這是 Notion API 設置的限制。

您會發現這不是可以想像到的最高效/最理想的解決方案,但考慮到要求和技術限制,這是我們能做的最好的。

對我們來說,這不是什麼大問題,因為我們可以使用 Next.js 中的“增量靜態再生”。接下來將緩存響應並在眨眼間為我們的博客提供服務。 (在此拉取請求中了解我們如何實現增量靜態再生的更多信息)

export const getPage = async (url: string) => {
  const allPosts = await getBlog();

  const blogId = allPosts.find(
    (blog) => blog.properties.Url.rich_text[0].plain_text === url
  )?.id;

  const page = await notion.pages.retrieve({ page_id: blogId });
  const title = page.properties.Name.title[0].plain_text;
  const intro = page.properties.Intro.rich_text[0].plain_text;

  const response = await notion.blocks.children.list({
    block_id: blogId,
    page_size: 100,
  });

  return {
    title,
    intro,
    content: response.results,
  };
};

顯示內容

一個概念頁面由“塊”列表組成,每個塊都有一個“類型”,指示它是普通文本還是不同類型的組件。

我們可以遍歷所有這些塊並渲染適當的 React 組件。

如果存在不支持的類型,則不會呈現任何內容。

const blogContent = useMemo(() => {
  return blog?.content?.map((block) => {
    switch (block.type) {
      case "paragraph":
        return (
          <Paragraph key={block.id}>
            {block.paragraph.text.map((text) => {
              if (text.href) {
                return (
                  <A key={text.text.content} href={text.href}>
                    {text.text.content}
                  </A>
                );
              }
              return text.text.content;
            })}
          </Paragraph>
        );

      case "heading_1":
        return <H2 key={block.id}>{block.heading_1.text[0]?.plain_text}</H2>;

      case "heading_2":
        return <H3 key={block.id}>{block.heading_2.text[0]?.plain_text}</H3>;

      case "bulleted_list_item":
        return <ListItem block={block} key={block.id} />;

      case "image":
        return (
          <ImageContainer key={block.id}>
            <StyledImage
              src={block.image.file.url}
              layout="fill"
              objectFit="contain"
            />
          </ImageContainer>
        );

      case "code":
        return (
          <CodeBlock
            key={block.id}
            text={block.code.text[0].plain_text}
            language={block.code.language}
          />
        );

      default:
        return null;
    }
  });
}, [blog]);

結束

我們給自己設定了以下要求

我們可以使用複選框來決定哪些內容是顯示和不顯示的

  • ✅ 使用直觀的編輯器編寫內容

Notion 是我最喜歡的工具,因為它易於使用。

  • ✅ 發布和取消發布文章,不需要對代碼進行任何更改

通過勾選 Notion 數據庫中的複選框即可發布和取消發布,輕而易舉。

  • ✅ 支持標記和富文本格式(標題、列表、鏈接、代碼塊......)

目前支持標題、列表、鏈接和代碼塊,如果將來這還不夠,我們可以輕鬆添加對其他組件的支持,例如引號。

  • ✅ SEO 友好的網址

我們可以完全自定義網址,以戰略性地使用重要的關鍵字來進一步提高我們的 SEO。

演示

管理顯示的文章

管理文章


下一篇
Tutorial JavaScript 教程
  1. JavaScript 中的模板字面量是如何工作的?

  2. 📊 計算 DORA 指標 - 部署頻率

  3. 您如何使用 chrome.tabs.getCurrent 在 Chrome 擴展程序中獲取頁面對象?

  4. 使用 Puppeteer 構建 Twitter 圖片下載器

  5. D3.js 和 Vue.js

  6. JavaScript 的新特性 - ES2020

  7. 用於 create-react-app 的 Docker 映像

  1. Firebase v9,無法從嵌套集合中獲取文檔

  2. 不完整的有效載荷 | React 和 Redux 工具包

  3. 如何評估 Javascript 數據網格

  4. 使用蜂群圖更好地可視化數據

  5. 使用 jQuery 在當前頁面中搜索

  6. 根據參數向特定頻道發送消息

  7. 與 Azure Advocates 的 25 天無服務器一起歡欣鼓舞

  1. 帶有 RxWeb 的 Angular 11+ FormGroup 數組

  2. jQuery UI 滑塊示例代碼複製粘貼並不起作用?

  3. 使用 Arduino 和 Node.js 控制 Motorbot

  4. 為什麼 React 如此受歡迎?