博主名單做成了一個(gè)可檢索網(wǎng)站:React 數(shù)據(jù)建模與 SEO 實(shí)踐)
做技術(shù)內(nèi)容項(xiàng)目久了手里自然會(huì)積累不少博主資料。最初這些資料都放在表格里博主名稱、粉絲數(shù)、CSDN 主頁(yè)、知乎、掘金、公眾號(hào)再加幾列合作記錄。表格自己看沒(méi)問(wèn)題一旦要給別人看事情就麻煩了。品牌方經(jīng)常會(huì)問(wèn)“有沒(méi)有長(zhǎng)期寫 Java 的博主”“這位作者除了 CSDN還在哪些平臺(tái)更新”“公眾號(hào)矩陣能不能單獨(dú)看”每次收到問(wèn)題我都要打開(kāi)文件、篩選、復(fù)制鏈接再重新整理一份。名單一多同一個(gè)博主可能在幾個(gè)項(xiàng)目表里重復(fù)出現(xiàn)粉絲數(shù)的寫法也五花八門。所以我做了一個(gè)小改造把部分公開(kāi)的技術(shù)博主資料放進(jìn)網(wǎng)站做成可以搜索、排序和直接訪問(wèn)主頁(yè)的頁(yè)面。它現(xiàn)在是 Dream 工作室合作博主矩陣 的一部分。這件事看著像“把 Excel 搬到網(wǎng)頁(yè)”真正動(dòng)手后卻涉及數(shù)據(jù)清洗、React 交互、頁(yè)面路由和 SEO。更有意思的是技術(shù)實(shí)現(xiàn)和內(nèi)容運(yùn)營(yíng)在這里剛好接上了。為什么不直接發(fā)一張名單截圖名單截圖是最快的做法。我以前也這么發(fā)過(guò)但很快就發(fā)現(xiàn)幾個(gè)問(wèn)題。第一截圖里的鏈接點(diǎn)不了。看到感興趣的博主后品牌方還得手動(dòng)搜索名字重名時(shí)不一定找得準(zhǔn)。第二名單會(huì)變。粉絲數(shù)增加、主頁(yè)地址調(diào)整、新博主加入都意味著重新截圖。舊圖片已經(jīng)散落在聊天記錄里很難統(tǒng)一更新。還有一個(gè)問(wèn)題與搜索有關(guān)。圖片里的名字和平臺(tái)信息搜索引擎未必能穩(wěn)定識(shí)別。即使識(shí)別到了也不知道每個(gè)名字對(duì)應(yīng)哪個(gè)鏈接。網(wǎng)頁(yè)中的文本、標(biāo)題和超鏈接更容易被理解也更方便后續(xù)維護(hù)。我最后保留了表格作為內(nèi)部工作文件網(wǎng)站只展示適合公開(kāi)的部分。兩者用途不一樣表格負(fù)責(zé)項(xiàng)目執(zhí)行網(wǎng)頁(yè)負(fù)責(zé)瀏覽、檢索和建立基本認(rèn)知。先把博主資料變成結(jié)構(gòu)化數(shù)據(jù)頁(yè)面第一版沒(méi)有接數(shù)據(jù)庫(kù)而是把資料整理成 TypeScript 數(shù)據(jù)。對(duì)于更新頻率不高的展示型網(wǎng)站這種方案夠直接也減少了后臺(tái)和接口的維護(hù)。每位博主的結(jié)構(gòu)大致如下exporttypeCreator{name:string;followers:string;csdn?:string;juejin?:string;zhihu?:string;wechat?:string;xiaohongshu?:string;};除了名稱和粉絲數(shù)其他字段都是可選的。原因很簡(jiǎn)單并不是每位作者都運(yùn)營(yíng)全部平臺(tái)。有的人主要寫 CSDN 和掘金有的人把精力放在公眾號(hào)還有作者會(huì)同步知乎或小紅書。數(shù)據(jù)結(jié)構(gòu)必須允許這些差異存在。一條實(shí)際數(shù)據(jù)是這樣的{name:一只牛博,followers:2.8W,csdn:https://blog.csdn.net/Mrxiao_bo,juejin:https://juejin.cn/user/1722263248317024,zhihu:https://www.zhihu.com/people/zhong-xian-sen-51-54/posts,wechat:https://mp.weixin.qq.com/s/ZFB23O8Bll-N60l8p87S_g}這里沒(méi)有存作者的私人聯(lián)系方式。網(wǎng)頁(yè)只放公開(kāi)主頁(yè)或公開(kāi)文章鏈接合作溝通仍通過(guò)工作室統(tǒng)一進(jìn)行。這樣既能讓品牌方查看作者內(nèi)容也不會(huì)把內(nèi)部資料直接暴露在網(wǎng)上。粉絲數(shù)排序比想象中麻煩我希望主理人 Dream 固定顯示在第一位其余博主按粉絲數(shù)從高到低排列。問(wèn)題是原始數(shù)據(jù)不是統(tǒng)一的數(shù)字20W、2.8w、8000、5047都存在中英文大小寫也不完全一致。如果直接按字符串排序8000可能會(huì)排在20W前面因?yàn)槌绦虮容^的是字符不是實(shí)際人數(shù)。于是我寫了一個(gè)很小的轉(zhuǎn)換函數(shù)functionfollowerValue(value:string){constnumberNumber.parseFloat(value.replace(/[^\d.]/g,))||0;return/w/i.test(value)?number*10000:number;}這段代碼先去掉數(shù)字和小數(shù)點(diǎn)以外的字符再判斷是否包含W。2.8W會(huì)轉(zhuǎn)成280008000則是8000之后才能正常排序。主理人固定在首位的邏輯單獨(dú)處理const[dream,...others]creators;constrankedCreators[dream,...others.sort((a,b)followerValue(b.followers)-followerValue(a.followers)),];這不是多高級(jí)的算法但它解決了真實(shí)數(shù)據(jù)里的臟格式。很多內(nèi)容項(xiàng)目的技術(shù)工作都類似難點(diǎn)不在算法本身而在輸入數(shù)據(jù)從來(lái)沒(méi)有想象中整齊。當(dāng)前轉(zhuǎn)換方式也有邊界。如果以后出現(xiàn)“1.2 萬(wàn)”“約 3k”或區(qū)間數(shù)據(jù)就需要繼續(xù)補(bǔ)規(guī)則。更穩(wěn)妥的長(zhǎng)期方案是同時(shí)保存展示文本和標(biāo)準(zhǔn)數(shù)值例如{followersLabel:2.8W,followersCount:28000}頁(yè)面顯示followersLabel排序使用followersCount?,F(xiàn)在的數(shù)據(jù)量還能人工檢查所以暫時(shí)沒(méi)有為了規(guī)范而做一次大遷移。搜索功能先做最小版本品牌方查看名單時(shí)最常見(jiàn)的動(dòng)作不是復(fù)雜篩選而是輸入一個(gè)名字確認(rèn)作者是否在列表中。因此第一版搜索只支持按博主名稱匹配。const [query, setQuery] useState(); const visible useMemo( () creators.filter(item item.name .toLowerCase() .includes(query.trim().toLowerCase()) ), [creators, query] );輸入變化后頁(yè)面在已有數(shù)組中進(jìn)行過(guò)濾。trim()用來(lái)處理前后空格轉(zhuǎn)成小寫則方便匹配英文名稱。技術(shù)博主數(shù)量在當(dāng)前規(guī)模下這種前端過(guò)濾已經(jīng)足夠快沒(méi)有必要為了一個(gè)輸入框單獨(dú)搭搜索服務(wù)。渲染平臺(tái)鏈接時(shí)我沒(méi)有給每位博主寫一套判斷而是先定義平臺(tái)字段與名稱的對(duì)應(yīng)關(guān)系constplatforms[[csdn,CSDN],[juejin,掘金],[zhihu,知乎],[wechat,公眾號(hào)],[xiaohongshu,小紅書],];組件遍歷這個(gè)數(shù)組字段存在就生成鏈接不存在就跳過(guò)。以后增加 51CTO 或華為云只要擴(kuò)展數(shù)據(jù)類型和平臺(tái)映射不用重寫整行 UI。這里我刻意沒(méi)有一開(kāi)始就做十幾個(gè)篩選項(xiàng)。方向標(biāo)簽、平臺(tái)組合、粉絲區(qū)間都可以繼續(xù)加但篩選條件越多維護(hù)數(shù)據(jù)的成本越高。先把名稱搜索和公開(kāi)主頁(yè)做好比堆一排暫時(shí)用不到的下拉框?qū)嶋H。為什么公眾號(hào)矩陣要單獨(dú)放在前面技術(shù)社區(qū)博主和公眾號(hào)作者有一部分重合但用戶查看它們時(shí)關(guān)注點(diǎn)不同。選擇 CSDN 博主時(shí)品牌方常會(huì)看技術(shù)方向、歷史教程和搜索表現(xiàn)。選擇公眾號(hào)時(shí)更關(guān)心賬號(hào)定位、訂閱讀者以及是否長(zhǎng)期寫 AI 或 IT 技術(shù)。兩類數(shù)據(jù)混在一個(gè)超長(zhǎng)列表里公眾號(hào)很容易被埋在后面。所以我把公眾號(hào)矩陣拆成獨(dú)立區(qū)域放在技術(shù)博主名單之前。公眾號(hào)數(shù)據(jù)也使用單獨(dú)的類型exporttypeWechatCreator{name:string;followers:string;wechat:string;category:AI/人工智能|IT技術(shù);};目前頁(yè)面精選展示部分公眾號(hào)作者整個(gè)合作矩陣是 100。技術(shù)內(nèi)容平臺(tái)的合作博主矩陣是 500網(wǎng)頁(yè)同樣只展示其中一部分。這個(gè)說(shuō)明必須寫清楚否則訪問(wèn)者容易把“當(dāng)前展示數(shù)量”和“全部資源數(shù)量”混為一談。粉絲數(shù)據(jù)也不是永久不變的。我在頁(yè)面底部加了提示說(shuō)明數(shù)據(jù)來(lái)自整理時(shí)的公開(kāi)信息后續(xù)可能隨平臺(tái)變化。這句話不夠漂亮但比把歷史數(shù)字當(dāng)成實(shí)時(shí)數(shù)據(jù)更誠(chéng)實(shí)。案例不能只剩一句“我們做過(guò)”博主名單解決的是“可以找誰(shuí)”案例頁(yè)面要回答“具體做過(guò)什么”。早期的網(wǎng)站文案只有項(xiàng)目名稱和一兩行結(jié)果用戶看完仍然無(wú)法判斷內(nèi)容質(zhì)量。后來(lái)我把重點(diǎn)項(xiàng)目做成獨(dú)立路由例如飛算 JavaAI、華為昇騰及鯤鵬、ToDesk 長(zhǎng)期內(nèi)容項(xiàng)目并補(bǔ)上公開(kāi)文章鏈接。案例數(shù)據(jù)同樣結(jié)構(gòu)化保存{slug:huawei-kunpeng-ascend,client:華為昇騰及鯤鵬,tag:國(guó)產(chǎn)算力生態(tài),result:150 位,resultLabel:萬(wàn)粉博主參與,metrics:[150 位萬(wàn)粉博主統(tǒng)一組織,300 篇技術(shù)文章規(guī)?;桓?覆蓋 16 個(gè)核心技術(shù)專題]}slug用來(lái)生成固定網(wǎng)址項(xiàng)目結(jié)果與公開(kāi)內(nèi)容在詳情頁(yè)呈現(xiàn)。這樣做有兩個(gè)好處品牌方可以直接把某個(gè)案例鏈接發(fā)給同事搜索引擎也能把每個(gè)項(xiàng)目當(dāng)成獨(dú)立頁(yè)面理解而不是只看到首頁(yè)上一張信息卡片。我越來(lái)越不喜歡“服務(wù)過(guò)眾多知名品牌”這種寫法。它聽(tīng)起來(lái)很滿信息卻很少。把參與規(guī)模、文章數(shù)量和公開(kāi)鏈接放出來(lái)讀者能自己判斷這比再加幾個(gè)形容詞有用。SEO 沒(méi)有神秘開(kāi)關(guān)先把頁(yè)面關(guān)系講清楚網(wǎng)站上線后我補(bǔ)了 Metadata、站點(diǎn)地圖、robots.txt和 JSON-LD。它們都不復(fù)雜作用也各不相同。Metadata 告訴搜索結(jié)果頁(yè)面該顯示什么標(biāo)題和描述。例如博主名單頁(yè)的配置是export const metadata { title: 合作博主名單, description: Dream內(nèi)容推廣工作室合作技術(shù)博主名單覆蓋 CSDN、掘金、知乎、微信公眾號(hào)等平臺(tái)。, alternates: { canonical: /creators }, };站點(diǎn)地圖負(fù)責(zé)列出首頁(yè)、服務(wù)頁(yè)和案例頁(yè)robots.txt再把站點(diǎn)地圖地址告訴搜索引擎。JSON-LD 則用結(jié)構(gòu)化方式說(shuō)明網(wǎng)站名稱、業(yè)務(wù)類型和服務(wù)范圍。這些配置只能幫助搜索引擎理解頁(yè)面不能替代內(nèi)容。真正決定頁(yè)面有沒(méi)有價(jià)值的還是里面是否提供了明確的信息。博主名單有公開(kāi)主頁(yè)案例頁(yè)有項(xiàng)目結(jié)果和文章鏈接服務(wù)頁(yè)說(shuō)明具體執(zhí)行方式。關(guān)鍵詞自然出現(xiàn)在這些內(nèi)容中不需要把“CSDN KOL 投放”機(jī)械地重復(fù)十幾遍。內(nèi)鏈也很重要。首頁(yè)可以進(jìn)入服務(wù)、案例和博主矩陣案例頁(yè)能返回其他項(xiàng)目名單頁(yè)則連接到各平臺(tái)公開(kāi)主頁(yè)。頁(yè)面不再是一座孤島訪問(wèn)者和搜索引擎都能順著鏈接繼續(xù)瀏覽。為什么我暫時(shí)沒(méi)有接數(shù)據(jù)庫(kù)和后臺(tái)從開(kāi)發(fā)角度看給博主資料做一個(gè)后臺(tái)很自然登錄、增刪改查、批量導(dǎo)入再配一套數(shù)據(jù)庫(kù)。問(wèn)題是系統(tǒng)復(fù)雜度會(huì)立刻上升?,F(xiàn)在網(wǎng)站展示的是精選公開(kāi)資料更新由我統(tǒng)一整理。使用 TypeScript 文件的優(yōu)點(diǎn)是改動(dòng)可審查、可以跟隨 Git 版本記錄部署后也沒(méi)有數(shù)據(jù)庫(kù)連接和后臺(tái)安全問(wèn)題。缺點(diǎn)同樣明顯批量更新不如表格方便非開(kāi)發(fā)人員也不適合直接修改代碼。什么時(shí)候值得接數(shù)據(jù)庫(kù)我給自己定了幾個(gè)判斷條件需要多人維護(hù)、更新頻率明顯增加、網(wǎng)頁(yè)要展示全部 500 博主或者需要按技術(shù)方向和合作狀態(tài)做組合檢索。到了那一步表格可以作為導(dǎo)入源網(wǎng)站通過(guò)后臺(tái)管理標(biāo)準(zhǔn)化數(shù)據(jù)。目前還沒(méi)到那個(gè)階段。過(guò)早做后臺(tái)最后可能花很多時(shí)間維護(hù)一套沒(méi)人使用的系統(tǒng)。技術(shù)頁(yè)面本身也是內(nèi)容做完這個(gè)頁(yè)面后我對(duì)“內(nèi)容”有了一個(gè)更具體的理解。內(nèi)容不一定都是長(zhǎng)文章。一份能搜索的博主目錄、一頁(yè)帶公開(kāi)鏈接的項(xiàng)目案例、一個(gè)解釋服務(wù)流程的頁(yè)面本身也是內(nèi)容而且比泛泛的品牌介紹更耐看。這與技術(shù)產(chǎn)品推廣的邏輯很接近。開(kāi)發(fā)者搜索問(wèn)題時(shí)希望盡快看到可驗(yàn)證的信息代碼、過(guò)程、數(shù)據(jù)或真實(shí)鏈接。品牌網(wǎng)站也一樣。把資料組織清楚比首頁(yè)堆滿口號(hào)更容易建立信任。Dream 內(nèi)容推廣工作室 現(xiàn)在主要提供技術(shù)內(nèi)容策劃、CSDN KOL 投放、公眾號(hào)博主推廣和多平臺(tái)內(nèi)容分發(fā)。網(wǎng)站沒(méi)有把所有內(nèi)容壓在首頁(yè)而是把服務(wù)、創(chuàng)作者和案例拆開(kāi)。對(duì)訪客來(lái)說(shuō)更好找對(duì)搜索收錄也更友好。這次改造留下的幾個(gè)實(shí)際結(jié)論第一先定義數(shù)據(jù)再設(shè)計(jì)頁(yè)面。原始名單沒(méi)有統(tǒng)一字段時(shí)界面畫得再漂亮也會(huì)被各種缺失值拖住。第二展示文本和計(jì)算數(shù)據(jù)最好分開(kāi)保存。2.8W適合人看28000適合排序。項(xiàng)目早期可以做轉(zhuǎn)換數(shù)據(jù)繼續(xù)增長(zhǎng)后應(yīng)當(dāng)從源頭標(biāo)準(zhǔn)化。第三公開(kāi)頁(yè)面只放公開(kāi)資料。主頁(yè)和文章鏈接足夠用于初步篩選私人聯(lián)系方式?jīng)]有必要進(jìn)入前端數(shù)據(jù)。最后是一個(gè)偏內(nèi)容的判斷少寫無(wú)法驗(yàn)證的形容詞多放能點(diǎn)開(kāi)的鏈接。一個(gè)網(wǎng)站是否可信往往不取決于它說(shuō)自己有多專業(yè)而在于用戶能不能順著頁(yè)面找到真實(shí)的人和真實(shí)的內(nèi)容。這套頁(yè)面還會(huì)繼續(xù)更新。下一步可能加入技術(shù)方向標(biāo)簽和更細(xì)的平臺(tái)篩選但我不會(huì)急著把它做成一個(gè)龐大的系統(tǒng)。先讓現(xiàn)有資料更容易查、更容易讀已經(jīng)解決了最常見(jiàn)的問(wèn)題。