Blog Cover Image

Inspire you to have New thinking, Walk out your unique Road.

[前端又變成小菜鳥] 前端框架的奇幻旅程 | SEO 那回事 | 從 Nuxt.js, Gridsome, Vue 一直到之後想學React.js 跟 Next.js

Posted on Dec 11, 2022

還記得 1 個多月前(10/10)我剛結束長達 6 個月運用休閒時間開發自己的個人網站,想起那個時候最尾兩三週真的是心情歷經三溫暖。

前言

沒想到才一個多月前的事,但我已經覺得是很久以前的事情了。

想到當時的情況,真的讓我壓力百分百,焦慮等級點滿,我記得約莫 8 月左右,我給自己訂了一個希望9月半能將網站順利上線的目標,於是在中秋連假(四天),我整整四天都在 coding,就是希望能趕在中秋節上線。

上線是上線了,不過當時我真的沒想到會遇到 SEO 的問題。

應該是說,我有想到,但是我還是決定嘗試看看,畢竟我當時其實並不了解這個技術的深層,只是想說也許可行?

你目前看到的這個網站,當初是我今年(2022 年)4 月時終於有時間有能力回來學前端,於是在先前表姐的提及下,我選了 Nuxt.js 做我的第一個前端框架學習,所以這個網站一開始是用 Nuxt.js 寫成的,但後來為什麼變回 Hugo 了?請聽我娓娓道來。

我在學 Nuxt.js 時雖然遇上蠻多困難,但很多都是我能夠自己 Google/自己嘗試學習,Nuxt.js 是基於 Vue.js 的延伸版,邏輯跟設定蠻多延伸 Vue.js,而且又有一些額外的功能 Nuxt.js 已經幫我們開發者處理好。

於是就在這個 Nuxt.js 的前端坑中玩耍開心了一陣子,心想我終於可以自己設計跟開發自己的個人網站了!

然而在 9/11 左右(中秋節連假順利把網站推上去後),觀察幾天 Google Analysis,發現後面幾天我的網頁瀏覽一天一天還低,然後原本排名前面的文章,瞬間掉下來,這是我心想:

糟糕,我擔心的 SEO 問題,居然最後還是發生了。

然後我告訴自己下一次要開發新專案時,不要一昧追求新技術,而是好好的跟根據需求去研究這些技術能不能達成目標

這篇文章其實蠻想紀錄自己在個人網站開發最尾那幾週的前端旅程故事(因為當時的我真的超焦慮+壓力爆棚),然後想寫一下自己從中學到什麼了。

Nuxt.js 的 SEO 設定問題

起初就有在思考會不會 SEO 有問題,目前使用 Hugo 時,當 generate 成完全靜態網頁後,會生產好一堆.html 檔,我的每篇部落格文章的 SEO 資訊都已經按照文章的內容跟設定寫好在.html 檔內,所以直接放在 Github 上+上寫好 sitemap,就可以讓 google bot 抓到我的網站跟文章內容,進而讓讀者搜尋到我的文章。

Hugo 本身就是 Github 上高星星數的 Static Site Generator (SSG) (靜態網頁生產器),還有其他 SSG 選項,像是: Jekyll, Vuepress ...等。我一開始是想說,我其實還沒學過任何前端框架(我以前學前端時,三大框架剛出現),所以想說挑個前端框架(Nuxt.js) 搭配一個 CSS Package (Tailwind.css),能夠算是嘗試自學跟自己做出一個自己的個人網站,無論是功能面或美術面都是。所以後來選了 Nuxt.js。至於,為什麼不是 Vue.js,...,我當初只是覺得 Nuxt.js 這個名稱酷斃了,就定下想用這個框架寫網站的目標 XDDD

使用過後的想法:

Nuxt.js 其實還沒辦法做到完全靜態,指令 generate 能夠產出.html 檔,可是你仔細去看 .html 檔內容應該會出現:

  • 每個.html 檔的 head 都一樣
  • 沒有 body,只有 javascript 檔

(應該就是 CSR (Client-Side Rendering)的技術概念了)

generate 雖然有產出 .html 檔,但是內容其實是使用者點進網站後, 內嵌的 javascript 才會根據目前的頁面 render 資料,並非剛開始就產好,所以 Google Bot 去爬蟲時,會爬到一樣的 SEO 內容,判定這個網站 SEO 都相同,不利於部落格文章特定的 SEO 內容。

雖然表姐有跟我說,請想想某些購物網站並不是靜態網站,他們都是有架伺服器的,那為什麼這些購物網站的 SEO 就這麼好?所以,並不是說要良好的 SEO,就一定要完全靜態網站。不過這個部分我還沒有去探討。

Nuxt.js 的 SEO 設定方式?

目前看到兩種,可以參考Nuxt.js 網站

  • Global Settings: 就是統一將 Meta Tags 寫在 root 的設定檔 nuxt.config.js
  • Local Settings: 就是如果需要客製化個別頁面的 SEO,就將 Meta Tags 寫在個別的.vue 檔script中。

優先度: Local Settings > Global Settings ,偵測到那一頁有設定 Local Settings 則會取代原本 Global Settings 設定的內容。

在這邊要道歉,我並不是排斥 Nuxt.js,其實這個框架很好很容易上手,而且我本人也沒有到研究的很透徹,因為他有幾種模式: Server side rendering, Static Site Generation,也許還有其他模式。

我照文件在 nuxt.config.js 設定檔中將網頁改為靜態生成,確實在執行指令後也都有生成.html 檔,只是真的內容還是有 client side rendering,就是使用者點入網頁才跳轉內容,並非一開始.html 內的內容就是固定的。

Render 文件的解釋,我也還是不理解,依據這個後端的腦袋,所以排列組合會有幾種嗎 QQ? (可惡的後端思維)

// Server Side Rendered Sites and Static Sites
export default {
  ssr: true
  target: static
}

// Client Side Rendering Only
export default {
  ssr: false
  target: static
}

// ??
export default {
  ssr: true
}

// ??
export default {
  ssr: false
}

我有嘗試把我當時的網站從靜態生產(Static Site Generation) 改為 Server side rendering (SSR),結果沒學過 SSR 的我,剛 run 起 SSR,就看到一堆錯 XD,在我努力嘗試幾下後,我被自己訂下很急的 deadline 打敗,開始尋找其他資源。

不過確實我覺得 SSR 也是我必經要學之路。

嘗試 Vuepress & Gridsome

我不想要這半年的努力白白浪費...

於是,我在某週的星期六,我帶上星巴克咖啡,坐在一座高牆上,一邊查找哪些框架是可以符合我的目標,然後一邊擔心自己這半年的努力會完全白費,我真的喜歡我自己設計的這個網站 style。

既 Nuxt.js 過後,我發現 SEO 沒辦法滿足我的需求,在評估我很希望自己能夠短時間內把開發好的內容搬到另外一個技術,然後那個技術具備優良的 SEO 體驗。

起初我還是不考慮 Hugo,因為考慮到我短期還沒有想要深入 Golang,於是為了符合 SEO,然後又希望能用到 JavaScript 框架,我找了幾個 SSG 靜態網站生產器的選項:

然後這是兩個備案,當時異想天開的覺得三大框架的核心都是 JS,應該長得很相似吧(?XD),所以看起來 Next.js 是基於 React.js 看起來星星數最多又很流行的框架,Hugo 是最後真的沒辦法順利用其他框架完成,最後的備案。

  • Next.js
  • Hugo 這兩個都是基於 Vue.js 框架延伸出來的靜態網站生產器技術,事不宜遲當週日我馬上就開始嘗試 Vuepress

Vuepress 開始嘗試沒多久,就暫時打住了,Vuepress 是以 md 檔為主要的靜態網頁生產器,而我的網站大量使用到 Tailwind.css + .vue 檔,好像一個頁面要對應一個 .md 檔的樣子,我的 Hugo 雖然是使用.md 檔來寫一個一個部落格文章,但是每個.md 檔對應 Vuepress 有自己規定的.md 檔規則,所以我有 400 多個.md 檔文章,我要對 400 多個.md 檔做內容的更換,起笑。

簡單來說,這是 Hugo .md檔 的格式

---
author: minayu416
title: ""
draft: true
date: 2022-12-11T23:39:20+08:00
status: published
categories:
  - ""
  - ""
type: "post"
description: ""
slug: ""
keywords:
  - test
image: ""
---

如果是用 Vuepress 的話, date 可能要改成其他字代替日期 (有點忘記了)。

再加上我發現 Vuepress 的結構跟 Nuxt.js 差蠻多的,我勢必又要一段時間學習,考慮到自己的目標是 快速上線+考慮到未來使用性,可能未來不會持續用 Vuepress,最後還是會考慮換個框架,畢竟星星數少加上很多外掛功能不齊全。

所以呢...好像嘗試沒到一天,就暫時打住了。

再來是 Gridsome

Gridsome 是我當初在查文章跟 Bug 時看到的,當初我覺得他的網頁做得很酷炫,又是基於 Vue.js 的 Jamstack framwork 框架(又一個新名詞!)。所以,我毫不猶豫開始拿起這個新玩具走跳一波。

Gridsome 星星數 8400 左右,其實不高。而且如果決定要使用 Gridsome 來開發的話,我要在學習GraphQL去撈資料,基於本人從事後端工程第三年終於修成仙,理解所謂的底層概念跟基礎觀念都一樣,會 Python 就會 Javascript,學 Golang 也很快上手,學習一個 GraphQL 應該不是太難的事。

確實雖然初期有點卡關,而且 GraphQL 的文件,我這個蠢呆萌看不太懂 QQ,不過順利的從我這廣大的 .md 檔文章撈出我想要的資料,然後 render 進網頁。

Gridsome 跟 Nuxt.js 真的有 87%像,幾乎快要可以無痛轉換,除了撈 .md 檔資料, Nuxt.js是使用 @nuxt/content,而 Gridsome 使用 GraphQL,其他 Girdsome 好像幾乎都有外掛是跟 Nuxt.js 相似,連 i18n 的功能都能處理的好好的。

要特別注意的是,如果是撈.md 檔的像是部落格頁面跟分類這種動態 route 網頁,要寫在./src/templates 裡,然後要去設定檔做設定(這邊不多說~)

但我前面已經說過,我最後回歸了 Hugo 的懷抱,所以 Gridsome 最後並沒有採用。

在我開始用 Gridsome 重構我的 Nuxt.js 個人網站後,一切都很順利,除了 GraphQL 偶爾卡的幾天,基本上都順暢流利,也預先 run generate 確實能產出完全靜態的網頁,我完成了 85%的重構後,來到了最後一哩路。

我有一頁網站是部落格的分類,要根據 .md 檔內不同的 Category 分類來篩選跟分類不同的文章類別,這個功能我只要在 route /category/:name帶入 name 這個參數,然後在從.md 檔取得資料時,篩選category = name,將屬於該分類的部落格文章撈出,然後 render 進該 category 網頁。

功能上沒什麼問題,但是失策的是,由於我的 Category 都是中文字,所以用 GraphQL 帶入中文字撈.md 檔資料會報錯(忘記是會報錯還是都沒撈到任何資料)。

// category = "[資訊那些事]"

<page-query>
  query Posts ($category: [String]){ posts: allBlogPost ( filter: { status: {eq:
  "published"}, categories: {contains: $category} } ) { edges { node{ title
  description date categories featuredpath featured slug } } } }
</page-query>

就是這樣,進入 category.vue 頁面後,$category 會直接吃到 route 帶進來的參數,然後直接做 query/filter。

結果就是一直報說在撈資料時有問題,在排除各種可能性後,我合理懷疑是因為我的 category title 都是中文字會有加解密跟編碼問題。

於是,encode+decode我也嘗試過了,然後 stackoverflow 翻過一遍了,最後在某個 Github 上看到 目前不支援非ancii文字

嗯...這麼說,就是卡了吧?我好像沒辦法做些什麼,除非要深入改 GraphQL 的框架,這並非我所樂見。

所以....,Gridsome 這個選項宣告...只好先擺著了。

Next.js & Hugo

在歷經 Vuepress + Gridsome 的重構嘗試後,約莫花了我一週的休閒時間,結果還是沒有辦法完成目標,所以在六日深夜思考過後,我決定來看看 Next.js,因為當初我在找 Nuxt.js 時,挖出一堆 Next.js 的資料,這兩個只有 u/e 不同啊,尤其網路上大部分資料都跟 Next.js 有關,當時也是過濾很久才找到我要找的答案。

於是在我天真的以為,三大前端框架就是都差不多的天真純真想法,我點入了Next.js 的官方網站,心想的:

不過就是架構會不太同,底層邏輯應該差不多吧?

這種天真無邪的想法,直接把我推入地獄 (阿不是),在某個週六我又一邊點著木質調蠟燭+Lofi 音樂配著清涼的無糖綠茶,打開 Next.js 頁面一邊看一邊覺得,怎麼這麼的不一樣...?

Next.js 是基於 React.js 延伸的框架,在我發現怎麼邏輯跟 vue 很不同後,我找了幾篇React.js vs Angular.js vs Vue.js相關的文章來壓壓驚一下,最後得出這個結論:

想簡單入門,請右轉 Vue, 想變前端大神,請左轉點 React.js

React.js 基本上都是用 JavaScript 來寫,當初好像就是創辦人覺得既然都是要用 Javascript 寫,為什麼不直接都寫 Javascript?

好像不像 vue 可以允許 html + css,目前看起來 React.js 都是用 JS 回傳 css+html。

嗯。。。。

學習曲線可能比當初的 Nuxt.js,我的個人網站很希望可以在短期內重購然後上線,我暫時沒打算再花半年學 React.js or Next.js 然後再重構我的網站。

所以最後呢?

在嘗試跟了解不同的框架後,Hugo 最後還是成為我經過深思熟慮過後的選擇。除了我本身陸陸續續對我以前的 Hugo 主題做小更改了解到的一些概念之外,Hugo 的設定跟架構我也很熟悉。而且大量的 html + css 也是我熟悉的語言。

我新網站除了前端頁面設計使用到 Tailwind.css 跟需要用原生 JavaScript 寫的像是 Navbar, Carousel 之類的功能,後端撈資料的功能基本上都跟舊 Hugo 主題完全相似,也就是說 Golang 語法可以直接百分之百照搬過來。而且 Hugo 目前也還是星星數很高的技術。

我一開始其實是很擔心 Hugo 會不會不能用npm, tailwind.css 這類型前端技術套件,因為我的新網站是廣泛用 tailwind.css,後來網路上其實有文章教導,所以這一步在一開始我確認可以在 Hugo 使用 Tailwind 後,危機就排除了。

所以 Hugo 是可以搭配 Tailwind.css 的!!

在經過約莫一週的時間,我成功用 Hugo 重構我本來 Nuxt.js 的框架,部署到 Github 上後沒出什麼太大的問題。

唯一一個我目前還不是太滿意的就是。

那個...

不知道你有沒有發現你用手機展開 Navbar 後,點外面關不起來,要點那個三條線的 Icon 才會再合起來?

我還不知道怎麼修 XDDD

萬惡的 Carousel 再換成 Hugo 用Hugo Carousel 外掛開發後,整個順的不要不要的,比本來在 Nuxt.js 用的 Carousel 套件還順,左滑右滑怎麼滑都順。

最後

這次的前端框架旅程真的是很有趣,我在後端玩耍了 3 年左右,後端還是有很多東西可以玩,但是加了前端可以讓外行人看了更開心 XD。

然後加上我又很愛嚐鮮,前端三大框架+上三大框架又延伸出一些其他的框架,有得玩了。然後玩出來的產物又可以架在 Vercel 上給人看,不像後端的程式都不知道怎麼讓人參考。

Angular.js 目前沒有引起我的注意,所以近期可能還不會想要學 Angular.js,下一個想接觸的框架應該是 React.js 跟 Next.js,依照我過往的習慣,喜歡先接觸很多不同的技術,最後再選定喜歡的那個。(阿不過後端語言很幸運的,接觸 Python 就很愛,就這麼一路學下去)

而且 Next.js 提倡的 Fully Static Site Generation 有吸引到我,究竟... Next.js 可否做到 SEO 友善呢?我爬文是可以的。

在這個個人網站結束後,我有陸續做了兩個前端專案當作練習,分別是用 Nuxt.js 跟 Vue.js 寫的。

Own Influence,你可能會覺得怎麼跟我的網站設計很像,嘿沒錯,我不希望 Nuxt.js 的六個月旅程是 0 產出,所以我把網站有關的內容換掉,然後保留 Nuxt.js 開發,並架設上 Vercel。

而明年我會開始開發 Miri 的下一個版本,會新開發網頁版本,目前還在考慮要不要就用 Next.js 或 React.js 去寫 Miri 的前端,這樣能夠學 React.js 又能幫 Miri 做出前端網頁,但是重點就是有沒有符合我要的需求,以及我未來是否還要用 React.js 當作 Miri 的前端框架。

還有諸多考量,但關於前端的旅程,React.js 跟 Vue.js 我會繼續體驗。

點進來的前端大大們請別轟炸,請記住,我是一個三年後端工程師思維的前端小菜鳥 @v@,

好啦,這篇就這,後會有期。