[{"data":1,"prerenderedAt":222},["ShallowReactive",2],{"blog:page:\u002Fvi\u002Fblog\u002Fbuild-time-content":3,"blog:articles:vi":161,"blog:translations:\u002Fvi\u002Fblog\u002Fbuild-time-content":219},{"id":4,"title":5,"author":6,"body":7,"cover":147,"coverAlt":147,"date":148,"description":149,"extension":150,"featured":151,"meta":152,"navigation":153,"path":154,"seo":155,"stem":156,"tags":157,"__hash__":160},"blog\u002Fvi\u002Fblog\u002F2.build-time-content\u002Findex.md","Content được resolve ở build time","John Martin",{"type":8,"value":9,"toc":140},"minimark",[10,14,18,25,30,53,57,109,112,116,119,125,128],[11,12,5],"h1",{"id":13},"content-được-resolve-ở-build-time",[15,16,17],"p",{},"Khi bạn mở một article ở đây, không server nào hỏi database rằng article đó\nnói gì. Câu trả lời đã được ghi xuống - thành một file HTML thuần - ngay lúc\nsite được build.",[15,19,20],{},[21,22],"img",{"alt":23,"src":24},"Sơ đồ pipeline: Markdown chảy qua static build và ra file HTML, CSS, SVG thuần","\u002Fassets\u002Fbuild-time-pipeline.svg",[26,27,29],"h2",{"id":28},"pipeline","Pipeline",[31,32,33,41,47],"ol",{},[34,35,36,40],"li",{},[37,38,39],"strong",{},"Viết"," - một article là một file Markdown có frontmatter, đặt cạnh ảnh\ncủa chính nó.",[34,42,43,46],{},[37,44,45],{},"Build"," - static build chạy mọi content query đúng một lần, trên máy\nbuild: listing, article featured, link trước\u002Fsau.",[34,48,49,52],{},[37,50,51],{},"Phục vụ"," - edge phục vụ file. Không có gì render theo từng request.",[26,54,56],{"id":55},"điều-đó-mua-được-gì","Điều đó mua được gì",[58,59,60,73],"table",{},[61,62,63],"thead",{},[64,65,66,70],"tr",{},[67,68,69],"th",{},"Mối quan tâm",[67,71,72],{},"Câu trả lời tĩnh",[74,75,76,85,93,101],"tbody",{},[64,77,78,82],{},[79,80,81],"td",{},"Độ trễ",[79,83,84],{},"CDN cache hit, không origin render",[64,86,87,90],{},[79,88,89],{},"Tính sẵn sàng",[79,91,92],{},"Site sống sót cả khi database chết",[64,94,95,98],{},[79,96,97],{},"Mô hình chi phí",[79,99,100],{},"Phục vụ file, không chạy compute",[64,102,103,106],{},[79,104,105],{},"Đúng content",[79,107,108],{},"Bạn đăng gì thì nó phục vụ đúng điều đó",[15,110,111],{},"Bảng trên là danh sách trung thực. Static generation không phải câu trả lời\nđúng cho mọi bề mặt sản phẩm, nhưng với bề mặt đọc thì khó có gì vượt được.",[26,113,115],{"id":114},"thoả-hiệp-ta-chấp-nhận","Thoả hiệp ta chấp nhận",[15,117,118],{},"Publish không còn tức thời: thay đổi content vào build kế tiếp. Với một blog,\nđó là thoả hiệp đúng - một deploy mất vài phút, và đổi lại, đường đọc không\nbao giờ phải chờ một query runtime.",[120,121,122],"blockquote",{},[15,123,124],{},"Một trang render từ file thì không thể có query chậm. Cả lớp sự cố đó đơn\ngiản không tồn tại với nó.",[126,127],"hr",{},[15,129,130],{},[131,132,133,134,139],"em",{},"Bài ",[135,136,138],"a",{"href":137},"\u002Fen\u002Fblog\u002Furl-model","mô hình URL"," nói về việc những file này kết thúc ở\nnhững địa chỉ localized sạch thế nào.",{"title":141,"searchDepth":142,"depth":142,"links":143},"",2,[144,145,146],{"id":28,"depth":142,"text":29},{"id":55,"depth":142,"text":56},{"id":114,"depth":142,"text":115},null,"2026-09-09","Vì sao blog này ship dưới dạng file prerender thay vì một content API - và điều đó mua được gì.","md",false,{},true,"\u002Fvi\u002Fblog\u002Fbuild-time-content",{"title":5,"description":149},"vi\u002Fblog\u002F2.build-time-content\u002Findex",[158,159],"architecture","static-sites","GJdQTqj05Cys87ydqEdGS5nCV4UWjXwoH6Da9RXlIus",[162,170,182,194,206,208],{"path":163,"stem":164,"title":165,"description":166,"date":167,"author":6,"tags":168,"featured":151},"\u002Fvi\u002Fblog\u002Fdemo-content-note","vi\u002Fblog\u002F6.demo-content-note\u002Findex","Blog này là gì (và không phải gì)","Đây là một vertical slice demo - layout thật, pipeline thật, content editorial một cách có chủ ý.","2026-10-07",[169],"meta",{"path":171,"stem":172,"title":173,"description":174,"date":175,"author":6,"tags":176,"featured":151,"cover":179},"\u002Fvi\u002Fblog\u002Freading-first-design","vi\u002Fblog\u002F5.reading-first-design\u002Findex","Trang đọc bài không phải trang tài liệu","Vì sao layout article của blog cố tình khác layout docs - phân cấp thông tin, bề rộng cột, và sự tiết chế.","2026-09-30",[177,178],"design","typography",{"src":180,"alt":181},"\u002Fassets\u002Fcover-reading-first.svg","Minh họa bìa: bố cục một cột hẹp được chọn thay vì bố cục nhiều cột rối rắm",{"path":183,"stem":184,"title":185,"description":186,"date":187,"author":6,"tags":188,"featured":151,"cover":191},"\u002Fvi\u002Fblog\u002Fstatic-deployment","vi\u002Fblog\u002F4.static-deployment\u002Findex","Deploy một blog như static assets","Không Worker script, không database binding - toàn bộ deployment là một thư mục file và một trang 404.","2026-09-23",[189,190],"deployment","cloudflare",{"src":192,"alt":193},"\u002Fassets\u002Fcover-static-deployment.svg","Minh họa bìa: thư mục các tệp HTML và SVG chảy ra mạng lưới edge CDN",{"path":195,"stem":196,"title":197,"description":198,"date":199,"author":6,"tags":200,"featured":151,"cover":203},"\u002Fvi\u002Fblog\u002Flocale-switching","vi\u002Fblog\u002F3.locale-switching\u002Findex","Locale switching không bao giờ nói dối","Language switcher chỉ được offer thứ tồn tại. Đây là cách danh sách link được suy ra từ content thật.","2026-09-16",[201,202],"i18n","ux",{"src":204,"alt":205},"\u002Fassets\u002Ftwo-locales-one-page.svg","Minh họa bìa: hai đường dẫn ngôn ngữ hội tụ về cùng một bố cục trang",{"path":154,"stem":156,"title":5,"description":149,"date":148,"author":6,"tags":207,"featured":151},[158,159],{"path":209,"stem":210,"title":211,"description":212,"date":213,"author":6,"tags":214,"featured":153,"cover":216},"\u002Fvi\u002Fblog\u002Furl-model","vi\u002Fblog\u002F1.url-model\u002Findex","Một mô hình URL cho mọi trang public","\u002Flocale\u002Fmount\u002Fpath giữ cho mọi trang public đoán được - và vì sao ta ràng buộc nó thay vì hy vọng nó được tuân thủ.","2026-09-02",[158,215],"urls",{"src":217,"alt":218},"\u002Fassets\u002Fcover-url-model.svg","Minh họa bìa: một thanh địa chỉ tách thành ba segment locale, mount và path",[220,221],"en","vi",1791809694217]