2026 માં શૂન્યથી કસ્ટમ બ્લોગ બનાવવો એ એક સભાન નિર્ણય છે. મોટાભાગના લેખકો ફક્ત એક હોસ્ટેડ પ્લેટફોર્મ પસંદ કરે છે અને આગળ વધી જાય છે. મેં મારો ટેક બ્લોગ Astro સાથે ફરીથી બનાવવા માટે નક્કી કર્યું કારણ કે હું સ્ટેકનું દરેક લેયર પોતે નિયંત્રિત કરવા માંગતો હતો અને એવા પેટર્ન શીખવા માંગતો હતો જે સ્ટેટિક સાઇટને માત્ર અલગ જ નહીં, પણ ખરેખર ઝડપી બનાવે. તેનું પરિણામ એક દ્વિભાષી સાઇટ છે જે જાપાનીઝ અને અંગ્રેજી કન્ટેન્ટ પૂરા પાડે છે, ડિફોલ્ટ તરીકે શૂન્ય JavaScript મોકલે છે, અને મુલાકાતીના બ્રાઉઝરને બદલે બધી જ જટિલતા મારી મશીન પર જ રાખે છે.
અહીં પાંચ પેટર્ન છે જેણે તેને સફળ બનાવ્યું.
Zod સાથે Content Collections
Astro ના Content Collections માત્ર Markdown ફાઇલોને ફોલ્ડર્સમાં ગોઠવવાનું કામ જ નથી કરતા. તેઓ તમારા કન્ટેન્ટ અને તમારા કોડ વચ્ચે એક કરાર (contract) લાગુ કરે છે. મેં દરેક આર્ટિકલ કલેક્શન સાથે Zod schema જોડ્યું છે, જેનો અર્થ છે કે કોઈપણ પેજ રેન્ડર થાય તે પહેલાં બિલ્ડ સ્ટેપ frontmatter ને વેલિડેટ કરે છે.
સ્કીમામાં language ફિલ્ડ જરૂરી છે જે ફક્ત બે જ કિંમતો સ્વીકારે છે: ja અથવા en. વાચકને કઈ ભાષા મળશે તે બાબતે કોઈ અસ્પષ્ટતા નથી. મેં એક pair ફિલ્ડ પણ ઉમેર્યું છે જે અનુવાદોને એકબીજા સાથે જોડે છે. જો હું જાપાનીઝમાં Astro વિશે પોસ્ટ પ્રકાશિત કરું અને પછી તેને અંગ્રેજીમાં અનુવાદિત કરું, તો બંને ફાઇલો એક જ pair ID શેર કરે છે. આનાથી લેંગ્વેજ સ્વિચર બનાવવું ખૂબ જ સરળ બની જાય છે કારણ કે સંબંધ ડેટામાં સ્પષ્ટ છે, ફાઇલના નામો પરથી અનુમાનિત નથી.
તારીખો Markdown frontmatter માંથી સ્ટ્રિંગ્સ તરીકે આવે છે, તેથી સ્કીમા તેને આપમેળે વાસ્તવિક Date ઓબ્જેક્ટ્સમાં રૂપાંતરિત કરે છે. આનાથી મારા પેજ ટેમ્પ્લેટ્સની અંદર સ્ટ્રિંગ-મેંગલિંગ (string-mangling) લોજિકની જરૂર રહેતી નથી. જોકે, સૌથી મોટો ફાયદો એ છે કે જો ભૂલ આવે તો તે તરત જ ખબર પડે છે (failure mode). જો કોઈ ફાઇલમાં જરૂરી ફિલ્ડ ખૂટતું હોય અથવા અમાન્ય લેંગ્વેજ કોડનો ઉપયોગ કરતું હોય, તો બિલ્ડ તરત જ સ્પષ્ટ ભૂલ સાથે ક્રેશ થઈ જાય છે. હું તેને ડિપ્લોયમેન્ટ પછી બગડેલા લેઆઉટ અથવા સાયલન્ટ 404 શોધવાને બદલે મારા ટર્મિનલમાં જ સુધારી લઉં છું.
આર્ટિકલ કન્વર્ઝન પાઇપલાઇન (Article Conversion Pipeline)
મેં પહેલા દિવસથી જ દરેક પોસ્ટ આ નવા ફોર્મેટમાં લખી નથી. વર્ષોનું કન્ટેન્ટ Zenn અને Dev.to પર હતું, જેમાં દરેક પ્લેટફોર્મની પોતાની વિશેષતાઓ અને પ્રોપ્રાઇટરી સિન્ટેક્સ (proprietary syntax) હતા. કોપી-પેસ્ટ કરીને હાથથી સુધારવાને બદલે, મેં એક TypeScript સ્ક્રિપ્ટ લખી જે આર્ટિકલ્સના આખા બેચને પ્રમાણભૂત Markdown માં રૂપાંતરિત કરે છે.
Zenn ટિપ્સ અને ચેતવણીઓ માટે કસ્ટમ callout સિન્ટેક્સનો ઉપયોગ કરે છે. મારી સ્ક્રિપ્ટ તેને સેમેન્ટિક HTML aside ટેગ્સમાં ફેરવે છે જેથી તેઓ આખી સાઇટ પર સમાન રીતે દેખાય. Dev.to એમ્બેડ્સ અને સ્પેશિયલ બ્લોક્સ માટે Liquid ટેગ્સ પર આધાર રાખે છે. આ પાઇપલાઇન તેને સાદા Markdown લિંક્સમાં રૂપાંતરિત કરે છે જે ક્યાંય પણ કામ કરે છે.
કેટલીક પોસ્ટ્સમાં માત્ર મૂળ પ્લેટફોર્મ માટે જ અસાઇડ્સ (asides) હોય છે, જેમ કે Medium પેવૉલ વિશે ડિસ્ક્લેમર અથવા Zenn-વિશિષ્ટ ઇમેજ પાથ. હું તેને HTML કોમેન્ટ્સમાં લપેટી દઉં છું જેથી કન્વર્ટર માઇગ્રેશન દરમિયાન તેને દૂર કરી શકે. સ્ક્રિપ્ટ ફાઇલોને લાઇન-બાય-લાઇન પ્રોસેસ કરે છે, પરંતુ તે કોડની સીમાઓનું સન્માન કરે છે. જ્યારે તે fenced code બ્લોક શોધી કાઢે છે, ત્યારે તે રૂપાંતરના નિયમોને સંપૂર્ણપણે છોડી દે છે. સિન્ટેક્સ સેમ્પલને બગાડવાથી ટેક બ્લોગનો આખો હેતુ નિષ્ફળ જઈ શકે છે, તેથી લાઇન-બાય-લાઇન પાર્સર કોડ બ્લોક્સને અસ્પૃશ્ય ઝોન તરીકે ગણે છે.
હવે માત્ર એક કમાન્ડ ચલાવવાથી એક પણ લિંક અથવા callout તોડ્યા વિના વર્ષોનું લખાણ ફરીથી પ્રકાશિત કરી શકાય છે.
બિલ્ડ-ટાઇમ OGP ઇમેજ જનરેશન (Build-Time OGP Image Generation)
સોશિયલ શેરિંગ ઇમેજીસ સામાન્ય રીતે પછીનો વિચાર હોય છે. તમે કાં તો તેને મેન્યુઅલી ડિઝાઇન કરો છો અથવા કોઈ હેવી રનટાઇમ સર્વિસ ઇન્સ્ટોલ કરો છો જે માંગણી મુજબ કાર્ડ્સ જનરેટ કરે છે. મારે આ બંને નથી જોઈતું. આ સાઇટ પરની દરેક Open Graph ઇમેજ બિલ્ડ દરમિયાન જ બનાવવામાં આવે છે જેથી મુલાકાતીઓને સ્ટેટિક PNG તરફ નિર્દેશિત કરતા હળવા img ટેગ સિવાય બીજું કંઈ ન મળે.
હું Satori નો ઉપયોગ કરું છું, જે JSX માર્કઅપ લે છે અને તેને SVG માં રેન્ડર કરે છે. આઉટપુટ સ્પષ્ટ, અનુમાનિત અને ટેમ્પલેટ બનાવવામાં સરળ છે. સાચું ઓપ્ટિમાઇઝેશન ફોન્ટ હેન્ડલિંગમાંથી આવ્યું છે. એક સંપૂર્ણ જાપાનીઝ વેબ ફોન્ટ સરળતાથી પાંચ મેગાબાઇટથી વધી શકે છે. બ્રાઉઝરને તેને ફેચ કરવા કહેવા તો દૂર, બિલ્ડ દરમિયાન તેને લોડ કરવું એ અસંગત હશે.
તેના બદલે, હું Google Fonts subsetting નો ઉપયોગ કરું છું. સ્ક્રિપ્ટ આપેલી પોસ્ટના ટાઇટલ ટેક્સ્ટની તપાસ કરે છે અને તે સ્ટ્રિંગને રેન્ડર કરવા માટે જરૂરી ચોક્કસ ગ્લિફ સેટ (glyph set) ની જ વિનંતી કરે છે. જો હેડલાઇનમાં ચાલીસ અનન્ય જાપાનીઝ અક્ષરો હોય, તો માત્ર તે ચાલીસ અક્ષરો જ નેટવર્ક પર ટ્રાન્સફર થશે. બિલ્ડ ઝડપી રહે છે, અને રેન્ડર થયેલી ઇમેજમાં ક્યારેય બ્રોકન ટોફુ બ્લોક્સ (broken tofu blocks) દેખાતા નથી કારણ કે સબસેટ ચોક્કસ છે. રનટાઇમ પર કંઈપણ છોડવામાં આવતું નથી.
Tailwind ટોકન્સ દ્વારા ડાર્ક મોડ (Dark Mode via Tailwind Tokens)
મેં દરેક એલિમેન્ટને dark: યુટિલિટી ક્લાસિસથી સજાવવાનો ઇનકાર કર્યો. તે અભિગમ સ્કેલ કરવામાં નબળો છે અને તમારા માર્કઅપમાં બિનજરૂરી અવાજ (noise) ભરે છે. મેં કલર ટોકન્સને જ ફરીથી વ્યાખ્યાયિત કર્યા જેથી સક્રિય થીમ (active theme) ના આધારે સમાન ક્લાસ નામ અલગ-અલગ કિંમતો આપે.
હું દરેક સપાટી (surface) અને ટેક્સ્ટ કલર માટે CSS custom properties નો ઉપયોગ કરું છું. લાઇટ મોડમાં, --color-white #ffffff સાથે મેપ થાય છે. ડાર્ક મોડમાં, સમાન વેરિએબલ નામ લગભગ કાળા (near-black) મૂલ્ય તરફ નિર્દેશ કરે છે. મારું HTML આ બાબતથી સંપૂર્ણપણે સ્વતંત્ર રહે છે. એક કાર્ડ દિવસના સમયની ચિંતા કર્યા વિના bg-ui-surface અને text-ui-primary નો ઉપયોગ કરી શકે છે. થીમ સ્વિચ રૂટ પર વેરિએબલ વ્યાખ્યાઓ બદલે છે, અને આખું ઇન્ટરફેસ તરત જ પ્રતિસાદ આપે છે.
આ અભિગમ સાથેનું એક જોખમ એ છે કે સ્ટાઇલશીટ્સ લોડ થાય તે પહેલાં લાઇટ કન્ટેન્ટનો ઝબકારો (flash) દેખાય છે. મેં તેને ડોક્યુમેન્ટના head માં એક નાના ઇનલાઇન સ્ક્રિપ્ટ દ્વારા ઉકેલ્યો છે. તે પ્રથમ પેઇન્ટ (first paint) પહેલા ચાલે છે, localStorage અને સિસ્ટમ પ્રેફરન્સ તપાસે છે, અને તરત જ સાચું ડેટા એટ્રિબ્યુટ સેટ કરે છે. સ્ક્રિપ્ટ માત્ર થોડા મિલીસેકન્ડ માટે રેન્ડરિંગને રોકે છે, તેથી વિઝિટર ડાર્ક મોડ શરૂ થાય તે પહેલાં ક્યારેય અણધારી સફેદ ઝબક (jarring white burst) જોતા નથી.
Island Architecture અને Zero-JS
Astro નો મુખ્ય સિદ્ધાંત એ છે કે પેજ સ્થિર (static) HTML તરીકે શરૂ થવું જોઈએ. જ્યારે ઇન્ટરેક્શનની ખરેખર જરૂર હોય ત્યારે જ JavaScript નો ઉપયોગ થાય છે. મેં આ વાતને ગંભીરતાથી લીધી છે.
મેં ગ્લોબલ મેનૂ અને થીમ ટોગલ માટે React નો ઉપયોગ ટાળ્યો છે. બંનેને સિંગલ મોડ્યુલમાં રહેલા થોડા પ્રમાણમાં vanilla JavaScript દ્વારા સંચાલિત કરવામાં આવે છે. તેમાં કોઈ hydration overhead, કોઈ virtual DOM diffing, અને ડાઉનલોડ કરવા માટે કોઈ framework runtime નથી.
હું ટેક્સ્ટમાંથી ડાયાગ્રામ રેન્ડર કરવા માટે Mermaid.js એકમાત્ર હેવી લાઇબ્રેરી તરીકે વાપરું છું. તેને ગ્લોબલ રીતે ઇમ્પોર્ટ કરવાને બદલે, મેં તેને Intersection Observer ની અંદર રેપ (wrap) કર્યું છે. ઓબ્ઝર્વર ડાયાગ્રામ કન્ટેનર્સ પર નજર રાખે છે. જ્યારે વપરાશકર્તા તેના થોડા સેંકડો પિક્સેલની અંદર સ્ક્રોલ કરે છે, ત્યારે સ્ક્રિપ્ટ ડાયનેમિકલી Mermaid મોડ્યુલ ઇન્જેક્ટ કરે છે અને ડાયાગ્રામ રેન્ડર કરે છે. જો પોસ્ટમાં કોઈ ડાયાગ્રામ ન હોય, તો તે લાઇબ્રેરી નેટવર્કને ક્યારેય સ્પર્શતી નથી. પ્રારંભિક પેજ લોડ હલકો રહે છે, અને બ્રાઉઝર માત્ર એટલું જ પ્રોસેસ કરે છે જે વાચક ખરેખર જુએ છે.
The Build-First Mindset
દરેક પેટર્નમાં ચાલતો મુખ્ય વિચાર સરળ છે: જો તમે બિલ્ડ દરમિયાન કામ કરી શકતા હોવ, તો તેને ત્યાં જ કરો. સાઇટ ડિપ્લોય થાય તે પહેલાં Zod સાથે તમારા ડેટાને વેલિડેટ કરો. રિક્વેસ્ટ સમયે કરવાને બદલે પ્રોપ્રાઇટરી પ્લેટફોર્મ સિન્ટેક્સને અગાઉથી જ કન્વર્ટ કરી લો. સર્વર ચાલુ કરવાને બદલે સોશિયલ ઈમેજીસને સ્ટેટિક ફાઇલોમાં રેન્ડર કરો. દરેક ક્લાયન્ટને લોજિક મોકલવાને બદલે ટોકન્સ દ્વારા થીમ કલર્સ નક્કી કરો. હેવી JavaScript ને ત્યાં સુધી મોકૂફ રાખો જ્યાં સુધી વપરાશકર્તાને ખરેખર તેની જરૂર ન હોય.
જટિલતાને બિલ્ડ સ્ટેપમાં (leftward) ખસેડવાથી રનટાઇમ અનુમાનિત (predictable) રહે છે, પેલોડ નાનો રહે છે, અને મેન્ટેનન્સનો બોજ સંભાળી શકાય તેવો રહે છે. સાઇટ કોઈ એક ટ્રિકને કારણે ઝડપી નથી રહેતી, પરંતુ એટલા માટે છે કારણ કે વિઝિટરના બ્રાઉઝરની અંદર બહુ ઓછી પ્રક્રિયાઓ થઈ રહી હોય છે. 2026 માં સ્ટેટિક આર્કિટેક્ચર પસંદ કરવાનો સાચો ફાયદો આ જ છે.
