教育產品:第一個月
原文由 Michael Lynch 于 發布,訂閱此部落格
一句話總結
我正要回頭重啟我的部落格課程。
重點摘要
- 我正在重啟 2020 年的部落格課程。
- htmx 還不錯,但還沒完全達到我期望的樣子。
- 我正在為 Is It Keto 這個舊的生酮飲食網站尋找買家。
重啟《Hit the Front Page》
2020 年,我做了一個關於部落格的影片課程,叫做《Hit the Front Page of Hacker News》。我對課程內容感到自豪,也收到了學生的正面回饋,但總覺得自己從來沒有給予它應有的關注。
當時課程上線時,TinyPilot 正快速成長,我沒有時間行銷課程或反覆打磨教材。
在上一篇文章中,我調查了讀者希望接下來看到我做什麼。在表示對我的教學有興趣的人當中,結果如下:

上一篇文章中讀者問卷的回覆結果
解讀數據的方式有很多,但我的結論是,大家特別希望我教寫作技巧。讓我意外的是,刻意練習也名列前茅,雖然熱度稍微低一點。
我認為,既然現有的課程已經幾乎完成,而且排名第二或第三(取決於怎麼算),我應該把舊教材整理一下,重新推出 2024 年的更新版。
尋找先導計畫的學員
Rob Fitzpatrick 的書Write Useful Books深深影響了我對教育產品的做法。他主張,在推出書籍或影片課程之前,一定要先現場教學一次,因為你需要根據真實學員的回饋來反覆改進。
我和太太也即將在八月底迎來第一個寶寶,到時候我打算消失幾個月專心陪家人。當我在考慮這門課時,距離預產期大約還有 10 週,而課程本身就要上 6 週,所以幾乎沒有什麼緩衝時間。
我寫了一段關於課程的簡介,並寄給部落格的訂閱者,請有興趣的人填寫一份簡短的申請表。有人填表後,我會針對他們在表單中寫的內容親自回覆,並附上付款連結來幫他們保留名額。
結果如下:
- 有 1,944 位訂閱者收到了關於課程的電子郵件。
- 有 11 人填寫了問卷表示有興趣。
- 有 7 人購買了課程。
- 在填了問卷卻未報名的 4 人中,有 3 人是因為時段衝突。
尋找視訊平台
讓我驚訝的是,視訊通話領域幾乎找不到 Zoom 以外可行的替代方案。自從他們被抓到在安全性上說謊之後,我就一直盡量避用 Zoom,但他們似乎仍是線上課程的唯一選擇。
過去幾年工作會議我都用 Jitsi Meet,體驗大致不錯,但參加 Zoom 會議時畫質明顯比較好。我本來想找 Jitsi Meet 的付費方案,但所有付費選項都標示「聯絡我們」,這通常代表一個月至少要 1,000 美元起跳。
所以,Jitsi 還算堪用,只是有點笨重。它不支援錄影,所以我的變通辦法是:
- 在筆電上主持課程的視訊通話。
- 再用桌機加入同一通話。
- 在桌機上用一般的螢幕錄影軟體錄製通話。
- 把影片上傳到PicoShare。
- 把 PicoShare 連結寄給全班。
這比我想要的複雜,但也有個意外的好處:即使我分享的投影片佔滿整個螢幕,我還是可以在桌機螢幕上看到所有人的臉。
如果你知道比 Jitsi Meet 更好的替代方案,請告訴我。
該不該淡化 Hacker News?
大約有一半報名的學員說,他們對 Hacker News 並沒有特別感興趣。他們只是喜歡我的寫作、想多了解我的寫作過程,所以即使課程聚焦在 Hacker News,他們還是報名了。
回頭看問卷數據,大家對廣義的寫作似乎比對部落格本身更有興趣。而且沒有人特別點名想學 Hacker News。
所以我在想,是否該把重心從 Hacker News 轉向更通用的主題。
我擔心一旦轉向,就會失去自己的優勢。教部落格或寫作的人有一大堆,在那個領域我很難脫穎而出。如果我專教 Hacker News,我就是這個領域最厲害的老師,因為根本沒別人在做這件事。
另一個問題是,我大部分部落格成功的證據都跟 Hacker News 有關。在個人部落客中,我在 Hacker News 上算是少見地成功。如果改教更通用的寫作課程,我的資歷就沒那麼亮眼了。我的部落格沒有賺很多錢,也沒有龐大的訂閱數可以拿來炫耀。
同時,我覺得會買我課程的人,多半是先認識我,才找到課程的。他們大概不是去搜尋「世界最強 Hacker News 專家」才找上門的。
或許重點是,我不需要太擔心和其他一大堆人競爭,因為無論如何,找到我課程的路徑大概都是透過我本人或口耳相傳。
這門課用原本聚焦 Hacker News 的形式已經完成了 95%,所以我打算先照原樣推出。結束之後,再把教材調整成更通用的課程。
學習 htmx
過去兩年,htmx 越來越常出現在我的視野中。我的朋友Cory Zue 有在使用 htmx,所以引起了我的興趣。
很長一段時間,最大的障礙就是我完全不懂 htmx 的意義在哪。
htmx 官網首頁的第一句話之一是:「為什麼只有 <a> 和 <form> 能發送 HTTP 請求?」我讀到這句時心想:「是啊,讓任何 HTML 元素都能發請求當然不錯,但 JavaScript 本來就能讓任何元素發送任何請求了。為了省幾行 JavaScript,就要採用一整套新方法嗎?」
真正讓我搞懂 htmx 的,是這本書:Hypermedia Systems。它由 htmx 的原作者所寫,解釋了 htmx 的動機,並詳細說明了幾個實際的應用場景。
如果要向四年前的自己推銷 htmx,我會這樣說。
給過去的自己的 htmx 推銷詞
還記得你剛學寫網站時,會這樣寫 HTML 嗎?
<form action="/users" method="POST">
<input name="first-name" placeholder="First name" />
<input name="last-name" placeholder="Last name" />
<input type="submit" value="Add user" />
</form>現在你不會這樣寫了,因為你想避免使用者送出表單時整個頁面重新載入。整頁重新載入又慢又讓人困惑,尤其如果你只是想顯示一句「使用者新增成功」。而且你也不想在伺服器退回輸入時,把使用者填好的資料全部清空。
所以,你會改用 JavaScript,寫成像這樣:
document.addEventListener("DOMContentLoaded", () => {
document.querySelector("form").addEventListener("submit", (evt) => {
evt.preventDefault(); // Block default submit.
fetch(`/users`, {
method: "POST",
credentials: "include",
headers: {
Accept: "application/json",
},
body: JSON.stringify({
firstName: document.querySelector("[name='first-name']"),
lastName: document.querySelector("[name='last-name']"),
}),
})
.then((response) => {
if (response.ok) {
return response.json();
}
// TODO: Handle errors too.
})
.then((result) => {
// TODO: Handle success.
});
});
});JavaScript 的量不算多,但每次需要表單就得重寫一次。你可以把重複的程式碼重構,但那會讓 UI 邏輯分散在好幾個檔案裡。每一次前端要跟伺服器互動,就得多一道阻礙。
或者你會轉向 React 或 Vue 這類厚重的框架,然後在你的程式碼和瀏覽器實際顯示的內容之間,就隔了無數層 JavaScript 抽象。
htmx 承諾的是回歸你剛學做網頁時的單純。與其寫完 HTML 再把所有邏輯丟給 React 或手寫的事件處理器,不如把 htmx 整合進應用程式,然後把表單寫成這樣:
<form hx-post="/users" hx-target="this">
<input name="first-name" placeholder="First name" />
<input name="last-name" placeholder="Last name" />
<input type="submit" value="Add user" />
</form>然後 htmx 會讓一切自動運作,完全不需要你寫任何客製化的 JavaScript。
我目前使用 htmx 的心得
為了試用 htmx,我一直在重寫 ScreenJournal 的部分功能。ScreenJournal 是我的開源電影評論 App,就像是電影版的 Goodreads。或者說,它是開源、比較陽春的 Letterboxd。

ScreenJournal 是我的興趣專案,一個用來寫電影評論的網頁 App。
重寫中一個不錯的例子是用 htmx 重新實作通知偏好設定頁面。我有一個頁面讓使用者設定想收到哪些 Email 通知:

ScreenJournal 上用來控制通知的頁面
通知頁面原本需要大量客製化 JavaScript 來處理以下事情:
- 透過
fetch送出表單內容,而不是重新載入頁面。 - 在請求進行中停用表單輸入。
- 在請求進行中顯示狀態讀取圖示。
- 如果請求失敗,顯示錯誤訊息。
以下是從原生 JavaScript 轉換到 htmx 的對比:
整體程式碼變少了,尤其是 JavaScript 少了很多。它把邏輯從前端移到後端,這是我比較喜歡的,因為我覺得後端程式碼比 UI 程式碼更容易測試。
以下是目前為止我使用 htmx 的一些心得:
htmx 多了一層抽象,但很直覺
- 用 Vue 和 Angular 時,我完全搞不懂它是如何把我的程式碼轉換成網頁 App 的。
- 用 htmx 時,它的行為夠直覺,我大概可以根據看到的運作方式,自己重新實作一套 htmx。
htmx 的錯誤處理不太理想
- htmx 的模型假設你向伺服器發送請求後,會把伺服器的回應放到頁面上的一個元素裡。
- 問題是,成功時我想替換掉 HTML 表單,但失敗時我想保留表單原樣,只在表單下方顯示錯誤。
- htmx 的解法是讓伺服器重新渲染包含使用者輸入的完整 HTML 表單,但我不喜歡這樣,因為那等於重新渲染一個本來就存在的東西,而且會增加 XSS 漏洞的風險。
- 我可以透過自己寫事件處理器來繞過這個問題,但那樣就感覺有點在跟框架對抗。
htmx 會弱化內容安全政策(CSP)
- 我喜歡把CSP當作防止跨站腳本攻擊(XSS)的最後一道防線。
- htmx 大致上與 CSP 相容,但正因為 htmx 能做這麼多事,攻擊者只要能寫入客製化的 HTML,就等同於能寫入任意的 JavaScript。
- 例如
<form action=/delete-account" method="post" onload="this.submit()">- CSP 會阻止這段程式碼執行。
<form hx-post="/delete-account" hx-trigger="load">- CSP 卻會允許這段等效的程式碼執行。
- 用 htmx 仍然可以寫出安全的應用程式,但它確實會讓 CSP 無法再作為防範 XSS 的可靠最後防線。
出售 Is It Keto
我這週發現 Amazon 在某個時間點改了聯盟行銷連結的做法,導致 Is It Keto 上 90% 的聯盟連結都失效了。網站還是能靠 Google AdSense 賺錢,但我已經沒有時間維護它了。
我正在尋找願意購買這個網站的人,如果是獨立創業者或想創業的人提出不錯的報價,我願意以低於市場行情的價格出售。
總結
完成了什麼?
- 開始以小班制教授我的部落格課程。
- 透過把 ScreenJournal 的大量功能移植到 htmx 來學習 htmx。
- 錄製了課程的第一段加分內容。
學到的教訓
- 我發現自己並沒有像想像中那樣被 Hacker News 這個角度綁住。
- 如果有人要上我的課,多半是因為喜歡我的寫作,而不是因為它在 Hacker News 上的表現,所以我應該多想想這樣的客群是什麼樣子。
下個月的目標
- 錄製四堂課可發布的版本。
- 開始販售新版課程。
需要協助的地方
視訊通話平台
如果你有符合以下條件的視訊通話平台建議,請告訴我:
- 必要:支援最多 10 人、90 分鐘的通話。
- 必要:參與者不需建立新帳號或在裝置上安裝軟體就能加入通話。
- 必要:費用在每月 80 美元以下。
- 加分:可錄製視訊通話。
課程平台的使用經驗
如果你曾以講師或學員的身分使用過像 Maven 或 Udacity 這類課程平台,請告訴我。
隨機一篇部落格
留言
登入後參與討論