Gatsby 內容網站

網站簡介

這是 project 其實就是我個人的部落格,做這個網站的時候剛好有個有趣的點子(至少目前我還沒在其它部落格看過),這是一個我取名「風格指數」的拉 bar 元件,讀者可以左右拉動一個 slider ,網站就會顯示某個特定風格的文章列表。

有興趣的話,點這裡去玩玩。

很幸運在現代,我可以用 React、Gatsby、Markdown 這樣方便的前端工具,能心想事成般的把自己心中的功能構想快速的實現。除了上述的「風格指數」功能,要弄出一些基本和進階的部落格功能都不是問題,例如:lazy load 相片、標籤、閃電般的搜尋、支援 Markdown 的 Content Manage System(CMS)… 等。

動機

構思這個 project 的主題的時候,是在做完一個 single page app (SPA) 的 project 之後。我就想到 SPA 就如大家所知的,不擅長 SEO(search engine optimization) ,搜尋引擎的排名較差,所以我就朝向 SEO 有利的網站架構思考。

同時間,剛好自己也需要一個分享技術文章的平台,雖然 medium 部落格的版型我是滿意的,但是有幾個我想要的功能沒有:

  1. 不強迫付費閱讀:我贊成讀者付費,而且很願意自己付費閱讀。但是我寫作最主要的目的只是為了組織自己的思考方式和交朋友,不是要靠寫作養活自己,所以並不想強迫大家付費閱讀我的文章。「medium 如果沒付費的讀者閱讀超過規定額度的文章,就需付費才能讀我的文章」,就不符合我目前寫作的目的。
  2. markdown 語法寫作:用 markdown 語法寫作非常快速,不用點滑鼠另外設定格式,有用過的人應該都愛不釋手,無奈大部份的部落格平台都不支援。
  3. 內嵌 code 分享: medium 可以支援 gist 之類的 code 分享,但是不支援內文直接寫 code ,對技術性的文章寫作支援還是不夠方便。
  4. SEO 控制在 medium 的演算法上,初期流量不足時,根本搜尋不到。

用 GatsbyJS 架站剛好就可以符合我的需求,可以用我擅長的 React library 操控 UI,配合 GatsbyJS 良好的資料處理模式,再串接一些現有很多免費好用的雲端服務,我可以從 0 到 1 自己刻出想要的功能和外觀。而且這種架構的靜態網站又有 SEO 的優點,剛好符合做這個 project 的初衷。

主要架構

這個網站主要放在 Netlify 的靜態網站,Netlify 可以設定成從 Github 的 repository 抓原始碼,然後自動發佈在 Netlify 的靜態網站上。

主要架構示意圖
主要架構示意圖

雖然開發的時候是在我自己的 mac 上開發,但是 push 上 Github 後,Netlify CI/CD 會把原始碼抓過來,開始執行 GatsbyJS 靜態網站產生器(static site generator),然後把 Contentful Content Manage System(CMS) 的 headless data 抓下來之後,先進行 server side rendering,最後產生一個仍具有動態功能的靜態網站。

部落格的文章都是用 Markdown 語法寫,儲存在 CMS 裡面,CMS 和靜態網站可以 webhooks 在一起,只要 CMS 有更新,可以自動觸發靜態網站把更新的內容抓過去,進行 rebuild。

靜態網站產生器 + CMS + 靜態網站的優點

這樣的架構很適合做為內容網站,主要優點如下:

  1. 只需要 JAM stack 就可以快速開發,而且可以利用 GatsbyJS 將各種資料整合在 graphQL 裡,搭配 React 開發出互動性高、功能複雜的網站。
  2. 同時經過 GatsbyJS 產生網頁之後,也會是一個 server side render(SSR) 完成的靜態網頁,同時具有 SSR 和 client side reder(CSR) 的優點,讓 client 端速度很快,高互動性。
  3. 因為是靜態網站,不需要維護後端和資料庫、安全性高、維護成本低,而且可以透過 Netlify 的 CDN 讓全球瀏覽網頁速度加快。
  4. Contentful CMS 支援 Markdown 語法預覽,可以用 CMS 完整的寫作 UI 進行寫作。
    用 CMS 寫作
    用 CMS 寫作
  5. 在任何有網路的地方都可以登入 CMS 進行寫作。發佈的時候,CMS 和 靜態網站之間的 webhooks 就會被觸發,更新網站內容。內容創作者並不一定需要在自己的開發環境下寫作,要發佈文章的時候,也不用在自己的開發環境下進行 build 和 deploy。
  6. 因為是有 route 的靜態網站,所以對 SEO 很有利。
  7. 內建圖片有 lazy load 功能,即使使用者網路環境不佳,使用者體驗也會不錯。
  8. 有設定 progressive web app(PWA) 的功能,讓網站速度飛快,而且在手機上可以有更接近 App 的體驗,甚至可以離線閱讀。
    在手機上的 app like 體驗
    在手機上的 app like 體驗

串接其它雲端服務

雖然是靜態網站沒有後端和資料庫,但仍保有React CSR的優勢,利用一些雲端 SAAS 服務的 API,仍然可以做出不少動態的功能:

  1. Algolia search:設定 indices 給 Algolia,就可以串接 Algolia 的服務,獲得飛速的站內搜尋。
    站內搜尋
    站內搜尋
  2. Facebook comments:讓讀者可以用臉書帳號對文章進行回應,增加互動性。
  3. Maichimp newsletter service:讓讀者可以訂閱電子報,有新文章的時候,自動收到通知。
  4. Formspree Email service:讓讀者可以不用離開網站,不用開自己的 Email,直接在網站中寄信給我。
  5. Gandi DNS register:我有向 Gandi 購買域名,將 CNAME 和 ALIAS 指向 Netlify,對 SEO 也有幫助。
  6. Google Analytics 4 和 Google Search Console:連接 Google 這兩個服務,可以了解內容的流量,也可以提高搜尋排名。在我還沒讓大家知道這個網站之前,Google 搜尋「蟲探理查」,已經是排名第一位。 SEO

其它功能和細節

除了串接雲端服務,另外還手刻了很多功能和細節,以下簡單介紹一下。

標籤

在 CMS 上就把標籤資料結構建立起來,再利用 GatsbyJS 依標籤找到的資料,自動產生該標籤頁的 route,並依據我用 React 建立的模版產生標籤的頁面。每篇文章具有的標籤也會連結到對應的標籤頁上,在標籤的頁面行動模式裡,可以橫向 scroll,點選不同的標籤。

手機版標籤功能
手機版標籤功能

導覽列

用 Bulma 純 css 套件來改,搭配用 React Hooks 寫出良好互動功能的 component。導覽列在桌面版上是完整展開的 drop down menu 的形式,而且具有良好的 mouse hover 體驗。在行動版上,右邊是用 hamburger 按鈕的形式,並且左邊可以顯現品牌,具有良好的窄螢幕瀏覽體驗。另外,每一個頁面下拉到一個程度,就會出現一個方便讀者 scroll top 的按鈕。

桌面版可以 hover;手機版良好觸控反應
桌面版可以 hover;手機版良好觸控反應

風格指數

作法其實有點類似標籤頁面,先在 CMS 上就先建立了一個風格指數可以填,也就是每一篇文章都有一個從 0~9 擇一的風格指數,用 GatsbyJS 依風格指數和我用 React 建立的模版建立起 10 個頁面,再用 Hooks 建立一個 0~9 的 range component,這個 component 的 slider 拉到某一個 integer 之後,就會自動把頁面導向那個風格指數的頁面。

另外,有個不容易被發現的小功能,在導覽列有一個「風格指數」的選項,我是讓它 link 到一個網頁,這個網頁會閃現有個會動的骰子,然後馬上就隨機的導向那 10 個風格指數網頁的其中任一頁,這樣點風格指數這個選項的時候,就會每次出現的風格指數網頁都不同。

風格指數
風格指數

另外,在每一篇文章都有一個風格的小 icon,這個小 icon 會依照該篇文章的風格指數不同,而有不同的顏色和不同的 icon 形狀,這個顏色和形狀是配合前面提到那個 range component 的顏色和形狀是一致的,而且這個 icon 點下去,就會去這個風格指數的頁面,也就是出現整頁篩選出相同風格指數的文章列表。

SEO 的細節

用了以下幾個方式來改善 SEO:

  1. 用的 JSX 語法都符合 HTLM 5 semantics,方便搜尋引擎的機器人讀懂網頁。
  2. relative route 名稱都和文章 title 相同。
  3. 有做 sitemap,提交給 Google Search Console,方便 Googlebot 爬取部落格。
  4. 利用 React Helmet 把文章的 meta data 寫入 head tag 裡面,也是方便 Googlebot 爬取資料。
  5. 有建立 Open Graph 的 meta data,讓文章在社群網站分享的時候,能夠有正確的預覽圖片和摘要。
    分享轉貼可以正確預覽
    分享轉貼可以正確預覽
  6. 也有建立 JSON-LD 格式的 meta data,有利 Googlebot 搜尋預覽。
  7. 網址都有意義,都是文章的標題和日期,也有助於 SEO。
  8. 有內嵌 Google Analytic 4 的程式碼,可以分析流量。

另外,因為 Google Analytic 4 有用 cookie,所以有弄一個讓讀者點選「同意」的 component,當使用者同意的話,才啟動 Google Analytic 4 的 cookie,以符合歐盟 GDPR 的規定。

markdown 寫作

除了 Gatsby 配合 Contentful 可以把 Markdown 轉變成 Html 格式,我還安裝了一些 plugin 讓文章可以內嵌程式的 code,而且可以依不同的程式語言上色,並且有 scroll bar 方便拉動檢視程式碼,也有複製 code 的按鈕可以按。

內嵌分享code的區域
內嵌分享code的區域

此外,文章裡面也可以內嵌 codepen、gist、youtube 等,也有像 medium 一樣的閱讀時間預估。另外,常見於自架部落格的行動版,會有 layout over flow 的情況,我也都用 css 強制斷字,而不會有奇怪的 over flow 顯示狀況。

訂閱

有灌一個 feed 的 plugin,所以部落格也可以進行 RSS 訂閱,RSS 訂閱的功能也可以觸發 mailchimp 裡面電子報的寄發。因此讀者可以訂閱 RSS 或是電子報,一但有新文章發佈於部落格,訂閱用戶就會自動更新。

訂閱相關功能
訂閱相關功能

設計

我沒有任何的設計背景,所以外觀設計和配色就儘量簡單為原則,小 icon 都用 fontawsome 套件,Logo 是自己用 figma 亂畫一通設計出來的,有些相片用 pixels 圖庫的相片。「關於」頁面區塊內容的分隔底緣,有用 clip path 的技巧切出不規則邊緣。

所有的頁面都是 mobile first RWD,CSS 的 frame work 是選用我最熟悉的 tachyons,一種 atomic css framework,class 重用性很高,提高網頁效能。

mobile first RWD
mobile first RWD

版面配置方面,所有頁面都設定在桌面版不會顯示過寬,如果視窗過寬,延伸出去的只有顏色,而沒有內容。按鈕、欄位、文章預覽…等,在桌面、平版、手機都有最適合的不同位置配置。

心得

上面拉裡拉雜的好像講了很多,其實沒有真的太深入講細節,實際做的時候當然有更多的細節需要處理,所以整個 project 花上不少時間才完成。不過我覺得非常值得,這樣實作學到很多特殊經驗和 know how,而且這些特殊的知識並不容易從書上或課堂上學到,甚至不容易 Google 得到。總之,很開心有自己的部落格,不需要依附在別人的平台上了,有需要什麼功能,都可以自己弄一個出來了。