π Membangun Website Pribadi Dinamis dengan GitHub Pages dan Google Sheets API. Studi Kasus: mustofin.com

Sebagai seorang profesional di bidang teknologi dan manajemen, serta memiliki ketertarikan di bidang pendidikan, aku ingin punya website pribadi yang dapat menampilkan data profil dan portfolio yang selalu mutakhir, tanpa perlu login ke CMS atau menyentuh kode setiap kali memperbarui informasi.
Akhirnya, tercetus proyek sederhana namun efisien:
mustofin.com β website statis dengan data dinamis dari Google Sheets API
π§© Arsitektur Solusi
Google Sheets (data profil & portfolio)
β API via Google Apps Script
Website Statis (HTML + Tailwind + JS)
β
Hosted on GitHub Pages
π’ GitHub Pages digunakan sebagai hosting statis β gratis, cepat, dan mudah di-deploy langsung dari repository.
π’ Google Sheets berperan sebagai βdatabase ringanβ yang bisa diperbarui kapan saja.
π’ Google Apps Script menyediakan endpoint API untuk mengubah data Sheet menjadi JSON.
π’ Vanilla JavaScript + TailwindCSS untuk menampilkan data di halaman web.
βοΈ Langkah Implementasi
1οΈβ£ Merancang Tampilan Web Profil & Portofolio
Pertama yang dilakukan adalah membuat struktur dan tampilan website utama.
/index.html β Beranda dan hero section
/about.html β Profil & pengalaman (CV Online) β diambil dari Google Sheets)
/portfolio.html β Daftar proyek dan hasil karya β diambil dari Google Sheets
/blog β redirect ke hashnode
/community.html β Keterlibatan di komunitas
/class.html β Kelas & Produk Digital β embed mayar.id
/contact.html β Kontak email dan sosial media
Tampilan menggunakan TailwindCSS agar tetap ringan tanpa framework besar.

2οΈβ£ Merancang Google Sheet sebagai Database
Membuat satu Google Sheet dengan beberapa sheet (tab) seperti: Portfolio, Profile, Experience, Education, Licenses, Skills, dan Master.

3οΈβ£ Membuat API dari Google Apps Script
Selanjutnya, menulis Google Apps Script untuk membaca data dari Sheet dan mengembalikannya dalam format JSON.
function doGet(e) {
try {
const page = e.parameter.page;
let result;
if (page === 'about') {
result = getProfileData();
} else {
result = getPortfolioData(e);
}
return createJsonResponse(result);
} catch (error) {
return createJsonResponse({ error: "An unexpected error occurred.", details: error.message }, 500);
}
}
Kemudian:
Klik Deploy β New Deployment β Web App
Pilih Execute as: Me (your account)
Pilih Who has access: Anyone
Klik Deploy dan salin URL API seperti:
https://script.google.com/macros/s/.../exec
4οΈβ£ Menampilkan Data ke Website
Di halaman about.html dan portfolio.html ditambah kode JavaScript untuk memanggil API dari Google Apps Script tadi, lalu menampilkan hasilnya ke halaman web.
function fetchFromAPI() {
grid.innerHTML = `<div class="loader-container col-span-3"><div class="loader"></div><p class="text-center text-gray-500">Memuat portofolio...</p></div>`;
fetch(apiUrl)
.then(response => {
if (!response.ok) throw new Error(`HTTP error! status: ${response.status}`);
return response.json();
})
.then(response => {
if (response.status === 'success' && response.data.length > 0) {
// Simpan data dan timestamp ke cache
const itemToCache = {
data: response.data,
timestamp: new Date().getTime()
};
localStorage.setItem(CACHE_KEY, JSON.stringify(itemToCache));
// Inisialisasi halaman dengan data baru
initializePage(response.data);
} else {
grid.innerHTML = '<p class="col-span-3 text-center text-gray-500">Tidak ada data portofolio untuk ditampilkan.</p>';
filterContainer.style.display = 'none';
}
})
.catch(error => {
console.error('Error fetching portfolio data:', error);
grid.innerHTML = '<p class="col-span-3 text-center text-red-500">Gagal memuat data. Silakan coba muat ulang halaman.</p>';
filterContainer.style.display = 'none';
});
}
5οΈβ£ Membuat Fitur Tambahan: Download CV Otomatis
Fitur terakhir yang dibuat adalah fitur Generate CV berdasarkan data profil yang sudah update di google sheet. Fitur dipasang langsung di file Google Sheet karena ada data sensitif yang akan tampil di CV hasil generate.
Hal pertama yang harus dilakukan untuk fitur ini adalah membuat template CV menggunakan google doc.

Lalu membuat google apps script untuk generate CV
function generateCvPdf() {
const data = getProfileDataFull();
const { profile, experience, education, licenses, skills } = data;
experience.reverse();
education.reverse();
const templateFile = DriveApp.getFileById(CV_TEMPLATE_ID);
const newFileName = `CV - ${profile.full_name || 'Resume'}.pdf`;
const outputFolder = DriveApp.getFolderById(FOLDER_OUTPUT_ID);
// Hapus file lama jika ada dengan nama yang sama agar tidak menumpuk
const oldFiles = outputFolder.getFilesByName(`${newFileName}.pdf`);
while (oldFiles.hasNext()) {
oldFiles.next().setTrashed(true);
}
const tempFile = templateFile.makeCopy(newFileName);
const docId = tempFile.getId();
try {
const doc = DocumentApp.openById(docId);
const body = doc.getBody();
// 1. Ganti placeholder simpel (Profile)
for (const key in profile) {
body.replaceText(`{{${key}}}`, profile[key] || '');
}
// 2. Ganti placeholder daftar (Skills)
const skillsText = skills.map(s => s.skill_name).join(' β’ ');
body.replaceText(`{{skills}}`, skillsText);
// 3. Proses bagian berulang dengan data yang urutannya sudah benar
processParagraphSection(body, experience, 'exp', 'start_date', 'description');
processParagraphSection(body, education, 'edu', 'institution_name', 'end_year');
processTableSection(body, licenses, 'lic', 'certification_name');
// Hapus placeholder yang tidak terisi agar bersih
body.replaceText("\\{\\{.*?\\}\\}", "");
doc.saveAndClose();
// Buat file PDF di folder tujuan
const pdfFile = outputFolder.createFile(tempFile.getAs(MimeType.PDF)).setName(`${newFileName}.pdf`);
return pdfFile;
} catch (error) {
Logger.log(`Gagal membuat PDF: ${error.toString()}\n${error.stack}`);
return ContentService.createTextOutput(`Gagal membuat PDF: ${error.toString()}`);
} finally {
// Pastikan file sementara selalu dihapus
DriveApp.getFileById(docId).setTrashed(true);
}
}
Fitur dipanggil melalui custom menu di google sheet, agar hanya kita yang memiliki akses.

6οΈβ£ Deployment
Untuk deploy website, menggunakan github page agar gratis, lalu beli domain mustofin.com untuk custom domain dari github page.

π‘ Hasil Akhir
Dengan kombinasi GitHub Pages + Google Sheets API, akhirnya berhasil membangun:
π Website profesional dengan domain custom (
mustofin.com)βοΈ Konten dinamis (profil & portofolio) tanpa CMS
π° Tanpa biaya hosting
π‘ Low maintenance, mudah diperbarui langsung dari Google Sheets
Bangun solusi kecil yang memberikan nilai nyata dan dapat berkembang secara iteratif.


