[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"site:languages:id":3,"site:navigation:id":22,"site:settings:id":148,"post:mengapa-kami-memodelkan-terjemahan-sebagai-baris-bukan-json:id":169,"post:related:mengapa-kami-memodelkan-terjemahan-sebagai-baris-bukan-json:id":248},[4,13],{"id":5,"code":6,"name":7,"nativeName":7,"direction":8,"flagEmoji":9,"isDefault":10,"isActive":10,"sortOrder":11,"createdAt":12,"updatedAt":12},"cms5x82ws0000p90jaubd6xdp","en","English","LTR","🇬🇧",true,0,"2026-07-29T10:07:30.747Z",{"id":14,"code":15,"name":16,"nativeName":17,"direction":8,"flagEmoji":18,"isDefault":19,"isActive":10,"sortOrder":20,"createdAt":21,"updatedAt":21},"cms5x82x90001p90je35iy8zx","id","Indonesian","Bahasa Indonesia","🇮🇩",false,1,"2026-07-29T10:07:30.766Z",{"HEADER":23,"FOOTER_PRIMARY":72,"FOOTER_SECONDARY":85,"LEGAL":106,"SOCIAL":122},[24,31,36,42,48,54,60,66],{"id":25,"href":26,"target":27,"icon":28,"sortOrder":11,"label":29,"caption":28,"children":30},"cms5x85l800nvp90jgvd1p33h","\u002F","_self",null,"Beranda",[],{"id":32,"href":33,"target":27,"icon":28,"sortOrder":20,"label":34,"caption":28,"children":35},"cms5x85lq00o1p90j6pq2ixue","\u002Fabout","Tentang",[],{"id":37,"href":38,"target":27,"icon":28,"sortOrder":39,"label":40,"caption":28,"children":41},"cms5x85m700o7p90jfrpuma9c","\u002Fservices",2,"Layanan",[],{"id":43,"href":44,"target":27,"icon":28,"sortOrder":45,"label":46,"caption":28,"children":47},"cms5x85ml00odp90jhbidzcte","\u002Fportfolio",3,"Portofolio",[],{"id":49,"href":50,"target":27,"icon":28,"sortOrder":51,"label":52,"caption":28,"children":53},"cms5x85mw00ojp90jm01w80sb","\u002Fcase-studies",4,"Studi Kasus",[],{"id":55,"href":56,"target":27,"icon":28,"sortOrder":57,"label":58,"caption":28,"children":59},"cms5x85n700opp90j8c67qr9t","\u002Fblog",5,"Blog",[],{"id":61,"href":62,"target":27,"icon":28,"sortOrder":63,"label":64,"caption":28,"children":65},"cms5x85nk00ovp90jzoeadygb","\u002Fcareers",6,"Karier",[],{"id":67,"href":68,"target":27,"icon":28,"sortOrder":69,"label":70,"caption":28,"children":71},"cms5x85nu00p1p90jb67ikv77","\u002Fcontact",7,"Kontak",[],[73,76,79,82],{"id":74,"href":33,"target":27,"icon":28,"sortOrder":11,"label":34,"caption":28,"children":75},"cms5x85od00p8p90j616esl9i",[],{"id":77,"href":62,"target":27,"icon":28,"sortOrder":20,"label":64,"caption":28,"children":78},"cms5x85ot00pep90jrto5fvh7",[],{"id":80,"href":50,"target":27,"icon":28,"sortOrder":39,"label":52,"caption":28,"children":81},"cms5x85p400pkp90jd8usqva3",[],{"id":83,"href":68,"target":27,"icon":28,"sortOrder":45,"label":70,"caption":28,"children":84},"cms5x85pg00pqp90jvlmbrz8q",[],[86,91,96,101],{"id":87,"href":88,"target":27,"icon":28,"sortOrder":11,"label":89,"caption":28,"children":90},"cms5x85q100pxp90juyka7vco","\u002Fservices\u002Fcustom-software-development","Perangkat Lunak Khusus",[],{"id":92,"href":93,"target":27,"icon":28,"sortOrder":20,"label":94,"caption":28,"children":95},"cms5x85qj00q3p90jdh85gytx","\u002Fservices\u002Fweb-platform-engineering","Platform Web",[],{"id":97,"href":98,"target":27,"icon":28,"sortOrder":39,"label":99,"caption":28,"children":100},"cms5x85r400q9p90jdhsjcffv","\u002Fservices\u002Fmobile-application-development","Aplikasi Mobile",[],{"id":102,"href":103,"target":27,"icon":28,"sortOrder":45,"label":104,"caption":28,"children":105},"cms5x85rw00qfp90j1rs0xc9k","\u002Fservices\u002Fcloud-devops","Cloud & DevOps",[],[107,112,117],{"id":108,"href":109,"target":27,"icon":28,"sortOrder":11,"label":110,"caption":28,"children":111},"cms5x85sm00qmp90jki97thzi","\u002Fprivacy","Kebijakan Privasi",[],{"id":113,"href":114,"target":27,"icon":28,"sortOrder":20,"label":115,"caption":28,"children":116},"cms5x85sw00qsp90j96hsi9if","\u002Fterms","Syarat & Ketentuan",[],{"id":118,"href":119,"target":27,"icon":28,"sortOrder":39,"label":120,"caption":28,"children":121},"cms5x85ta00qyp90je9qxvdrq","\u002Ffaq","FAQ",[],[123,130,136,142],{"id":124,"href":125,"target":126,"icon":127,"sortOrder":11,"label":128,"caption":28,"children":129},"cms5x85to00r5p90jlpp2dj9y","https:\u002F\u002Flinkedin.com\u002Fcompany\u002Fmoodkuit","_blank","linkedin","LinkedIn",[],{"id":131,"href":132,"target":126,"icon":133,"sortOrder":20,"label":134,"caption":28,"children":135},"cms5x85u000rbp90jz220we6w","https:\u002F\u002Fgithub.com\u002Fmoodkuit","github","GitHub",[],{"id":137,"href":138,"target":126,"icon":139,"sortOrder":39,"label":140,"caption":28,"children":141},"cms5x85uc00rhp90j909vvybj","https:\u002F\u002Fx.com\u002Fmoodkuit","x","X",[],{"id":143,"href":144,"target":126,"icon":145,"sortOrder":45,"label":146,"caption":28,"children":147},"cms5x85un00rnp90j4c6x21gw","https:\u002F\u002Finstagram.com\u002Fmoodkuit","instagram","Instagram",[],{"site.name":149,"site.shortName":150,"site.logo_dark":151,"site.logo_light":152,"site.url":153,"site.defaultLocale":6,"contact.email":154,"contact.sales_email":155,"contact.phone":156,"contact.whatsapp":157,"contact.address":158,"contact.map_embed_url":159,"contact.office_hours":160,"company.legal_name":149,"company.founded":161,"seo.default_title":162,"seo.default_description":163,"seo.twitter_handle":164,"seo.default_og_image":165,"social.links":166,"features.newsletter_enabled":167,"features.blog_enabled":167,"features.careers_enabled":167,"integrations.google_analytics_id":168,"integrations.recaptcha_site_key":168},"PT Moodkuit Solutions Technologies","Moodkuit","\u002Fimages\u002Flogo\u002Fblack-logo.png","\u002Fimages\u002Flogo\u002Fwhite-logo.png","https:\u002F\u002Fmoodkuit.com","hello@moodkuit.com","sales@moodkuit.com","+62 21 5010 8899","+62 812 1000 8899","Menara Kuningan, 12th Floor, Jl. H. R. Rasuna Said, Jakarta Selatan 12940, Indonesia","https:\u002F\u002Fmaps.google.com\u002F?q=-6.2238,106.8317","Mon–Fri, 09:00–18:00 WIB","2018","Moodkuit — Enterprise Software House","Moodkuit designs, builds and operates enterprise software platforms — custom systems, web, mobile, cloud and data.","@moodkuit","\u002Fimages\u002Fhero\u002Fhero-slider.jpg","[{\"platform\":\"linkedin\",\"url\":\"https:\u002F\u002Flinkedin.com\u002Fcompany\u002Fmoodkuit\"},{\"platform\":\"github\",\"url\":\"https:\u002F\u002Fgithub.com\u002Fmoodkuit\"},{\"platform\":\"x\",\"url\":\"https:\u002F\u002Fx.com\u002Fmoodkuit\"},{\"platform\":\"instagram\",\"url\":\"https:\u002F\u002Finstagram.com\u002Fmoodkuit\"}]","true","",{"id":170,"authorId":171,"coverImageId":172,"status":173,"publishedAt":174,"readingMinutes":51,"viewCount":175,"isFeatured":10,"allowComments":19,"createdAt":176,"updatedAt":177,"deletedAt":28,"coverImage":178,"author":192,"categories":196,"tags":212,"translation":240},"cms5x84i100b5p90j5aybdulu","cms5x83ok0035p90j1tmyvb7d","cms5x83y2005tp90jglrwh85p","PUBLISHED","2026-05-17T09:00:00.000Z",11,"2026-07-29T10:07:32.810Z","2026-07-29T12:58:11.777Z",{"id":172,"folderId":179,"uploadedById":180,"type":181,"filename":182,"originalName":182,"mimeType":183,"size":184,"width":185,"height":186,"storageKey":187,"url":188,"thumbnailUrl":188,"alt":189,"caption":28,"blurhash":28,"createdAt":190,"updatedAt":191,"deletedAt":28},"cms5x83pu003jp90j5lwg5qs2","cms5x83o00034p90jw5cmslod","IMAGE","post-1.jpg","image\u002Fjpeg",52352,850,402,"seed\u002Fpost\u002Fwhy-we-model-translations-as-rows-not-json\u002Fpost-1.jpg","https:\u002F\u002Fcdn.moodkuit.com\u002Fmoodkuit\u002Fseed\u002Fpost\u002Fwhy-we-model-translations-as-rows-not-json\u002Fpost-1.jpg","Database schema sketch comparing JSON blobs with translation tables","2026-07-29T10:07:32.090Z","2026-07-29T10:31:55.693Z",{"id":171,"name":193,"avatarUrl":194,"bio":195},"Rani Prameswari","\u002Fimages\u002Fnews\u002Fauthor_img2.jpg","Design systems practitioner and the byline on most of the engineering blog.",[197],{"postId":170,"categoryId":198,"category":199},"cms5x84dx00a0p90jq4hj1xcq",{"id":198,"parentId":28,"sortOrder":11,"createdAt":200,"updatedAt":200,"deletedAt":28,"translations":201},"2026-07-29T10:07:32.661Z",[202,207],{"id":203,"categoryId":198,"locale":6,"name":204,"slug":205,"description":28,"seoTitle":28,"seoDescription":28,"createdAt":206,"updatedAt":206},"cms5x84e300a2p90jrmk5oan0","Engineering","engineering","2026-07-29T10:07:32.667Z",{"id":208,"categoryId":198,"locale":15,"name":209,"slug":210,"description":28,"seoTitle":28,"seoDescription":28,"createdAt":211,"updatedAt":211},"cms5x84e900a4p90jp567w33d","Rekayasa","rekayasa","2026-07-29T10:07:32.674Z",[213,226],{"postId":170,"tagId":214,"tag":215},"cms5x84ge00app90jkr79ffxv",{"id":214,"createdAt":216,"updatedAt":216,"translations":217},"2026-07-29T10:07:32.750Z",[218,223],{"id":219,"tagId":214,"locale":6,"name":220,"slug":221,"description":28,"createdAt":222,"updatedAt":222},"cms5x84gk00arp90jw496y388","PostgreSQL","postgresql","2026-07-29T10:07:32.756Z",{"id":224,"tagId":214,"locale":15,"name":220,"slug":221,"description":28,"createdAt":225,"updatedAt":225},"cms5x84gp00atp90joaw62cvh","2026-07-29T10:07:32.761Z",{"postId":170,"tagId":227,"tag":228},"cms5x84gz00aup90jdptxkdy4",{"id":227,"createdAt":229,"updatedAt":229,"translations":230},"2026-07-29T10:07:32.772Z",[231,236],{"id":232,"tagId":227,"locale":6,"name":233,"slug":234,"description":28,"createdAt":235,"updatedAt":235},"cms5x84h500awp90jlbo8nn5n","Architecture","architecture","2026-07-29T10:07:32.778Z",{"id":237,"tagId":227,"locale":15,"name":238,"slug":234,"description":28,"createdAt":239,"updatedAt":239},"cms5x84hd00ayp90je3b4lt5p","Arsitektur","2026-07-29T10:07:32.785Z",{"id":241,"postId":170,"locale":15,"title":242,"slug":243,"excerpt":244,"content":245,"seoTitle":246,"seoDescription":244,"seoKeywords":28,"canonicalUrl":28,"ogImageUrl":28,"noIndex":19,"noFollow":19,"createdAt":247,"updatedAt":247},"cms5x84ik00b9p90jmkopb6ke","Mengapa kami memodelkan terjemahan sebagai baris, bukan JSON","mengapa-kami-memodelkan-terjemahan-sebagai-baris-bukan-json","Blob terjemahan JSON terasa praktis sampai Anda perlu menemukan setiap judul yang belum diterjemahkan. Tabel terjemahan relasional hanya menambah satu join dan menjawabnya dalam milidetik.","\u003Cp>Menyimpan terjemahan dalam kolom JSON tampak pragmatis. Satu kolom, tanpa join, tanpa migrasi saat menambah locale. Tagihannya datang belakangan.\u003C\u002Fp>\u003Ch2>Yang rusak\u003C\u002Fh2>\u003Cp>Pelaporan cakupan terjemahan menjadi pemindaian tabel penuh dengan ekspresi JSON path. Keunikan slug per locale tidak dapat ditegakkan basis data. Indeks parsial untuk konten terpublikasi per locale tidak tersedia.\u003C\u002Fp>\u003Ch2>Yang kami lakukan\u003C\u002Fh2>\u003Cp>Setiap entitas yang dapat diterjemahkan memiliki tabel pendamping dengan kunci \u003Ccode>(entity_id, locale)\u003C\u002Fcode> dan batasan unik kedua pada \u003Ccode>(locale, slug)\u003C\u002Fcode>. Menambah bahasa Jepang cukup satu insert ke tabel \u003Ccode>languages\u003C\u002Fcode>.\u003C\u002Fp>","Mengapa kami memodelkan terjemahan sebagai baris, bukan JSON | Moodkuit","2026-07-29T10:07:32.828Z",[249,272],{"id":250,"authorId":171,"coverImageId":251,"status":173,"publishedAt":252,"readingMinutes":51,"viewCount":253,"isFeatured":19,"allowComments":19,"createdAt":254,"updatedAt":255,"deletedAt":28,"coverImage":256,"translation":264},"cms5x84kj00bnp90j5qo7aas1","cms5x83yk005zp90jsek60xg4","2026-06-10T09:00:00.000Z",16,"2026-07-29T10:07:32.899Z","2026-07-29T13:22:52.647Z",{"id":251,"folderId":179,"uploadedById":180,"type":181,"filename":257,"originalName":257,"mimeType":183,"size":258,"width":185,"height":186,"storageKey":259,"url":260,"thumbnailUrl":260,"alt":261,"caption":28,"blurhash":28,"createdAt":262,"updatedAt":263,"deletedAt":28},"post-4.jpg",36028,"seed\u002Fpost\u002Fcore-web-vitals-budgets-that-survive-the-second-sprint\u002Fpost-4.jpg","https:\u002F\u002Fcdn.moodkuit.com\u002Fmoodkuit\u002Fseed\u002Fpost\u002Fcore-web-vitals-budgets-that-survive-the-second-sprint\u002Fpost-4.jpg","Performance budget failing a continuous integration run","2026-07-29T10:07:32.108Z","2026-07-29T10:31:55.623Z",{"id":265,"postId":250,"locale":15,"title":266,"slug":267,"excerpt":268,"content":269,"seoTitle":270,"seoDescription":268,"seoKeywords":28,"canonicalUrl":28,"ogImageUrl":28,"noIndex":19,"noFollow":19,"createdAt":271,"updatedAt":271},"cms5x84kr00brp90jge79ik4t","Anggaran Core Web Vitals yang bertahan sampai sprint kedua","anggaran-core-web-vitals-yang-bertahan-sampai-sprint-kedua","Skor Lighthouse saat rilis hanyalah potret. Anggaran di CI adalah jaminan.","\u003Cp>Regresi performa datang satu impor sepele setiap kali. Perbaikannya bersifat struktural: anggaran ditegakkan di CI, dan build gagal saat LCP atau ukuran bundel melewati batas.\u003C\u002Fp>","Anggaran Core Web Vitals yang bertahan sampai sprint kedua | Moodkuit","2026-07-29T10:07:32.907Z",{"id":273,"authorId":171,"coverImageId":274,"status":173,"publishedAt":275,"readingMinutes":57,"viewCount":276,"isFeatured":19,"allowComments":19,"createdAt":277,"updatedAt":278,"deletedAt":28,"coverImage":279,"translation":287},"cms5x84j900bbp90jgvsq13h5","cms5x83y9005vp90j0shkjq4a","2026-05-25T09:00:00.000Z",12,"2026-07-29T10:07:32.853Z","2026-07-29T13:33:30.533Z",{"id":274,"folderId":179,"uploadedById":180,"type":181,"filename":280,"originalName":280,"mimeType":183,"size":281,"width":185,"height":186,"storageKey":282,"url":283,"thumbnailUrl":283,"alt":284,"caption":28,"blurhash":28,"createdAt":285,"updatedAt":286,"deletedAt":28},"post-2.jpg",30668,"seed\u002Fpost\u002Fshipping-a-multilingual-site-without-duplicating-your-codebase\u002Fpost-2.jpg","https:\u002F\u002Fcdn.moodkuit.com\u002Fmoodkuit\u002Fseed\u002Fpost\u002Fshipping-a-multilingual-site-without-duplicating-your-codebase\u002Fpost-2.jpg","Locale-prefixed routes mapped out on a whiteboard","2026-07-29T10:07:32.097Z","2026-07-29T10:31:55.658Z",{"id":288,"postId":273,"locale":15,"title":289,"slug":290,"excerpt":291,"content":292,"seoTitle":293,"seoDescription":291,"seoKeywords":28,"canonicalUrl":28,"ogImageUrl":28,"noIndex":19,"noFollow":19,"createdAt":294,"updatedAt":294},"cms5x84jh00bfp90jcufpo2op","Merilis situs multibahasa tanpa menggandakan basis kode","merilis-situs-multibahasa-tanpa-menggandakan-basis-kode","Routing berprefiks locale, hreflang, URL canonical, dan slug per locale — ditangani sekali di router.","\u003Cp>Sebagian besar situs multibahasa keliru di tempat yang sama: URL. Begitu slug berbeda per locale, routing naif memaksa halaman ganda atau URL berbahasa Inggris di mana-mana.\u003C\u002Fp>\u003Ch2>Kontrak routing\u003C\u002Fh2>\u003Cp>Locale default disajikan tanpa prefiks. Locale lain diberi prefiks. Slug diselesaikan per locale dari basis data, dan setiap halaman memancarkan set lengkap \u003Ccode>hreflang\u003C\u002Fcode> beserta \u003Ccode>x-default\u003C\u002Fcode>.\u003C\u002Fp>","Merilis situs multibahasa tanpa menggandakan basis kode | Moodkuit","2026-07-29T10:07:32.861Z"]