
Sinergi Group: Situs Perusahaan Bilingual yang Sengaja Server-Rendered
- Ibrahim Fiqhan
- Website
- 20 Juli 2026
Daftar Isi
Sinergi Group adalah perusahaan konstruksi dan fabrikasi di Jawa Timur yang berjalan di bawah dua badan usaha: CV. Sinergi Utama dan PT. Sembada Sinergi Karya. Mereka membutuhkan situs publik yang bisa ditemukan calon klien melalui Google, dalam bahasa Indonesia maupun Inggris.
Mereka juga membutuhkan sistem internal untuk menjalankan proyek konstruksi, yang saya tuliskan secara terpisah.
Keduanya berada dalam satu basis kode Laravel. Cara merendernya sama sekali berbeda, dan justru di situlah bagian yang disengaja.
Dua strategi rendering dalam satu aplikasi
Aplikasi internalnya memakai Inertia dan React. Dirender di sisi klien, berada di balik login, dan itu tidak masalah karena mesin pencari tidak akan pernah melihatnya.
Halaman publiknya memakai Blade murni, dirender di server. Tanpa React, tanpa hydration, tanpa perlu JavaScript untuk membaca satu kata pun.
Pemisahan itu bukan soal selera, melainkan batasan yang saya sepakati. Klien tidak ingin ada proses Node berjalan di server mereka, dan itu langsung menyingkirkan mode SSR milik Inertia. Maka server-side rendering harus berbasis PHP, dan jika berbasis PHP, Blade adalah jawabannya alih-alih sesuatu yang lebih rumit.
Saya menonaktifkan Inertia SSR di konfigurasi alih-alih membiarkannya tersedia, lalu menuliskan alasannya di berkas panduan proyek, karena “aktifkan saja SSR-nya” justru saran yang paling mungkin diajukan kontributor berikutnya dengan niat baik.
Satu sumber terjemahan untuk dua stack
Situs ini berjalan dalam bahasa Indonesia dan Inggris, dan teksnya dipakai bersama sisi React dari aplikasi. Menyelaraskan dua sistem terjemahan jelas tidak akan berhasil.
Karena itu sumbernya satu: lang/en.json dan lang/id.json yang bersarang, diakses dengan notasi titik.
React membacanya melalui hook useTranslation. Blade membacanya melalui helper t() kecil yang saya tulis lalu daftarkan lewat autoload files milik Composer.
Helper itu ada karena satu alasan yang agak menjengkelkan. Fungsi __() bawaan Laravel tidak membaca JSON bersarang — ia memperlakukan seluruh string bertitik sebagai satu kunci datar lalu mengembalikannya begitu saja. Anda harus mendatarkan seluruh berkas terjemahan, atau menulis helper empat baris. Saya memilih menulis helper.
Locale diambil dari parameter ?locale=id|en, diterapkan oleh middleware, dan disimpan di session.
Pekerjaan SEO-nya
Setiap halaman publik mendeklarasikan title, meta_description, meta_keywords, dan canonical miliknya sendiri, lalu layout bersama menyusunnya menjadi meta tag, tag Open Graph, dan JSON-LD.
Ada route sitemap.xml yang dihasilkan dari konten sebenarnya alih-alih dipelihara manual, karena sitemap yang ditulis tangan biasanya kedaluwarsa dalam sebulan.
Satu hal kecil yang saya perbaiki dan sebelumnya diam-diam salah: layout menambahkan - Sinergi Group pada setiap title, sementara beberapa halaman juga menyertakannya sendiri. Semua title terbaca “Sesuatu - Sinergi Group - Sinergi Group”. Mudah terlewat, padahal itulah bagian halaman yang ditampilkan Google.
Menyamai design system React di dalam Blade
Halaman publik harus tampak identik dengan komponen berbasis shadcn milik aplikasi, tetapi Blade tidak punya akses ke varian cva maupun tailwind-merge.
Jadi kelas Tailwind pada template Blade didatarkan secara manual dari komponen React: base ditambah variant ditambah size, dengan konflik diselesaikan sebagaimana tailwind-merge akan menyelesaikannya. Membosankan, tetapi berhasil.
Ikonnya berupa SVG inline melalui komponen Blade yang membungkus set Lucide, sehingga halaman publik tidak mengirimkan font ikon maupun JavaScript ikon.
Formulirnya POST biasa. @csrf, pengisian ulang old(), tampilan $errors, lalu redirect kembali dengan pesan flash. Formulir kontak memasukkan email ke queue alih-alih mengirimkannya di dalam request.
Diuji pada bagian yang penting
Halaman publik memiliki pengujian fitur Pest yang mencakup hal-hal yang benar-benar merugikan bila rusak: bahwa title dirender di sisi server, bahwa ?locale=id mengganti kontennya, bahwa filter tag portofolio berfungsi, dan bahwa validasi yang gagal mengembalikan input pengguna alih-alih formulir kosong.
Pengujian itu ada karena keluaran SEO yang dirender server termasuk hal yang rusak tanpa suara. Tidak ada yang menyadari meta description hilang sampai trafiknya turun.
Deployment
GitHub Actions saat push, dengan development dan main dipetakan ke dua environment. Aset dibangun di CI, public/build/ dikirim via rsync, lalu composer install --no-dev, migrate --force, dan optimize.
Server hanya membutuhkan PHP. Tidak ada daemon Node, yang memang menjadi batasan awalnya, dan proses deploy menjalankan queue:restart agar worker yang sedang berjalan menyelesaikan job saat itu alih-alih melanjutkan dengan kode baru.
Yang akan saya bawa ke proyek berikutnya
Pemisahan dua strategi rendering ini layak dipakai ulang. Halaman publik memperoleh HTML yang dirender server karena kemudahan ditemukan adalah seluruh tugasnya; aplikasi yang terautentikasi memperoleh klien yang kaya karena tidak ada yang meng-crawl-nya.
Default framework mendorong Anda memilih satu lalu menerapkannya di mana-mana. Tidak ada aturan yang mewajibkan itu.
Kunjungi situsnya atau hubungi saya jika ingin membangun yang serupa.

Siap membangun proyek bersama saya?
Saya siap membantu membangun, mengembangkan, dan meluncurkan proyek Anda berikutnya — kirim pesan sekarang dan ayo kita mulai!
Mulai Sekarang




