Panduan Developer

Menulis widget layar utama dengan JavaScript sederhana — sinkron, tanpa async/await, dengan cache-fallback otomatis.

Mulai dalam 60 detik

Buka app Safar WidgetSkrip Baru → tempel kode di bawah → ▶ Run (pratinjau + konsol) → Simpan → buat Instance → tahan layar utama → tambah widget "Safar Widget" → Edit Widget → pilih instance-mu.
const w = Widget.create({ padding: 14, background: '#06201E' });
w.text('Halo dunia', { size: 18, weight: 'bold', color: '#FFFFFF' });
w.countdown('2027-01-01T00:00:00+07:00', { size: 14, color: '#34C759' });
Widget.present(w);

Model eksekusi: sinkron & berbatas waktu

API runtime

APIKeterangan
Widget.paramsObjek parameter instance (diisi di app; per-widget)
Widget.device{family: 'small'|'medium'|'large', locale, darkMode}
Widget.create(opts){padding, background (hex/Gradient), url, spacing, align}
Widget.present(w) / Widget.refreshAfter(menit)Serahkan pohon / saran refresh berikutnya
http.getJSON(url, o) · getText · posto = {timeout, headers}; gagal & tanpa cache → throw
cache.get(k) / cache.set(k, v)KV kecil per-skrip, persisten lintas render
console.log(...)Tampil di konsol editor (di widget dibuang)
Gradient.vertical(...) / horizontalLatar gradien untuk background

Node tampilan (builder)

PemanggilanHasil
w.text(teks, props)Teks. props: {size, weight: 'regular'|'medium'|'semibold'|'bold', color, lineLimit, minScale}
w.countdown(tanggal, props)Hitung mundur hidup (berdetak tanpa refresh); ISO 8601 atau Date
w.clock(props)Jam saat render (statis — batas WidgetKit)
w.progress(nilai, props)Bar 0–1. {color, track, height}
w.spacer(px?) / w.divider(props)Celah tetap / fleksibel; garis pemisah
w.hstack(opts) / w.vstack(opts)Kembalikan builder anak; {spacing, align}

Modul bawaan (offline, tanpa unduhan)

ModulAPI
Sholathitung({tanggal:'YYYY-MM-DD', lat, lng, tzMenit, metode:'kemenag'|'mwl', koreksiMenit}){subuh…isya}, tiap item {jam:'HH:mm', menit}. Perkiraan astronomis — selalu tampilkan anjuran mengikuti jadwal masjid.
HijriahdariMasehi(date, koreksiHari){hari, bulan, tahun, namaBulan, namaHari, teks} (tabular; sediakan koreksi ±2 hari)

Bedanya dari Scriptable

Skrip Scriptable tidak bisa ditempel langsungColor, ListWidget, Request, Font adalah API milik app Scriptable. Safar Widget memakai API sendiri yang lebih kecil supaya satu skrip kelak berjalan identik di iOS dan Android. Perbedaan utama: sinkron (tanpa await), builder deklaratif (bukan addText/addStack imperatif), cache-fallback bawaan runtime, token/rahasia lewat parameter instance — bukan diedit di dalam skrip.

Berbagi skrip

Dari editor, tombol Bagikan membungkus skrip sebagai berkas .safarwidget yang bisa dikirim lewat WhatsApp/AirDrop/Files. Penerima yang sudah memasang Safar Widget cukup mengetuk berkasnya — app terbuka dan menampilkan seluruh isi skrip untuk diperiksa sebelum disimpan. Bundel tidak pernah memuat parameter instance (di sanalah token/kunci API tinggal), jadi rahasia pengirim tidak ikut terbagi. Tautan safarwidget://impor?d=<base64url> juga didukung.

Kiat

Contoh siap pakai

Semua pola di atas hidup di katalog template — dari kartu teks sederhana sampai dashboard haji & umroh multi-API, dan setiap template divalidasi mesin terhadap runtime yang sama dengan aplikasi.

Khusus pelaku haji & umroh ada grup tersendiri, tersaring per peran: jamaah (kartu identitas, panduan thawaf & sa'i, jadwal obat), travel (kursi paket, pelunasan, visa, manifest, target penjualan), land arrangement (okupansi hotel, kedatangan grup, armada, katering), muttawif (headcount, agenda, briefing cuaca), dan ustadz (materi kajian, dalil manasik, progres bimbingan).