source.unsplash.com Sudah Tidak Ada: Post-Mortem dan Semua Cara Menggantinya
Dihentikan (deprecated) pada 2021 dengan janji “existing uses will continue to work”, dimatikan total pada Juni 2024, dan masih saja ditulis ke kode baru hingga hari ini. Post-mortem yang terukur — beserta tiga pengganti, termasuk proxy yang mengembalikan keacakan tanpa API key.
Sebuah layanan stock photo mematikan satu subdomain, dan dua tahun kemudian subdomain itu masih merusak situs dokumentasi, halaman login, latihan kursus, dan kode yang baru saja dihasilkan. Ini adalah post-mortem sebuah URL — apa fungsinya, apa yang mematikannya, dan apa yang harus dipasang sebagai penggantinya — plus tinjauan yang terukur pada bagian yang lebih aneh dari cerita ini: mesin yang menulis kode kita ternyata belum sadar URL itu sudah tidak ada.
Respons HTTP, dua entri changelog yang dikutip kata demi kata, batas API, pelacak isu dari proyek-proyek yang rusak, serta jumlah dari GitHub, npm, dan Stack Overflow — semuanya berasal dari sumber primer, dengan metode untuk masing-masing ada di catatan kaki. Jika Anda hanya ingin solusinya, langsung saja ke tabel migrasi.
Apa yang Anda dapat hari ini, jika masih meminta URL itu
Satu perintah, tanpa kunci, dapat direproduksi dari mesin mana pun:
curl -I https://source.unsplash.com/random
HTTP/2 503
cache-control: no-cache, no-store
content-type: text/html; charset=utf-8
server: Heroku
via: 2.0 heroku-router
# body: sebuah iframe yang mengarah ke herokucdn.com/error-pages/application-error.html
Ini bukan kegagalan DNS. source.unsplash.com masih dapat di-resolve — statusnya adalah CNAME ke
host herokudns.com — jadi permintaannya tetap dijawab, hanya saja bukan oleh sebuah aplikasi. Detail
ini lebih penting dari kelihatannya: browser yang menerima 503 dengan cepat beserta body HTML
akan menampilkan placeholder gambar rusak, dan kode apa pun yang membaca response.ok atau
handler onerror yang tidak pernah Anda tulis akan mengambil jalur kegagalan yang tidak pernah Anda uji.
| Pola URL | Dulu mengembalikan apa | Sekarang |
|---|---|---|
source.unsplash.com/random | Foto acak, ukuran apa pun | 503 |
source.unsplash.com/random/1600x900 | Foto acak, dipotong sesuai ukuran | 503 |
source.unsplash.com/1600x900/?apple,desk | Foto acak yang cocok dengan kata kunci pencarian | 503 |
source.unsplash.com/featured/1600x900?nature | Foto featured secara acak | 503 |
source.unsplash.com/collection/190727/800x600 | Foto acak dari sebuah koleksi | 503 |
source.unsplash.com/user/scottwebb/1600x900 | Foto acak dari satu fotografer | 503 |
source.unsplash.com/daily | Foto hari ini | 503 |
Diperiksa satu per satu dengan curl -o /dev/null -w "%{http_code}". Fitur pencarian
dihentikan lebih dulu, sesuai pengumuman; hari ini seluruh aplikasi sudah mati, jadi perbedaan
itu sudah tidak relevan lagi.
Tiga tahun antara “deprecated” dan “mati”
Kedua pengumuman itu masih bisa dibaca, dalam satu tempat, di unsplash.com/documentation/changelog. Dikutip lengkap, karena redaksinya adalah keseluruhan ceritanya:
25 November 2021 — “Unsplash Source being deprecated”
“Unsplash Source is being deprecated. Existing uses will continue to work, however for new projects use the full Unsplash API.”
11 Juni 2024 — “Unsplash Source sunset”
“Unsplash Source has been officially unsupported since its deprecation in 2021. As part of the final sunsetting, we will first wind down by disabling the search feature, and in the coming weeks turn off the application entirely. Existing uses of Source — particularly production-level ones — should migrate as soon as possible to the full Unsplash API.”
Baca keduanya secara berurutan dan pola kegagalannya jadi jelas. Pemberitahuan tahun 2021 memuat sebuah janji (existing uses will continue to work) dan tanpa tanggal. Developer yang membacanya di tahun 2021 punya alasan penuh untuk membiarkan kode yang berjalan tetap seperti apa adanya; developer yang bergabung di tahun 2022 sama sekali tidak pernah membacanya. Pemberitahuan 2024 memberi kabar “beberapa minggu ke depan”, tiga tahun kemudian, di halaman yang tidak pernah di-bookmark siapa pun.
Unsplash memang mempublikasikan kebijakan deprecation, dan itu kebijakan yang masuk akal — dokumentasinya
menyatakan bahwa untuk field dan endpoint yang didokumentasikan secara publik, perubahan diumumkan
di changelog dengan pemberitahuan minimal 3 minggu, dan endpoint mengembalikan
header Warning selama periode deprecation. Paragraf yang sama memuat kalimat yang
menjelaskan mengapa tak satu pun dari itu melindungi Source: “For any non-publicly documented
fields or endpoints, we may make changes to these with no warning.” Source tidak pernah menjadi
endpoint dari API yang terdokumentasi. Ia berada di luar kebijakan yang seharusnya melindunginya.
- Pelajaran praktisnya bukan “Unsplash ceroboh”. Melainkan bahwa URL yang bisa Anda pakai tanpa membaca dokumentasi apa pun adalah URL yang kebijakan deprecation-nya juga belum pernah Anda baca.
- Kerusakan sudah terjadi sebelum pengumuman. Sebuah isu Drupal yang diajukan pada 28 November 2022 sudah melaporkan “I get always a Heroku application error”, delapan belas bulan sebelum entri sunset. Kegagalan yang terputus-putus (intermiten) adalah cara layanan seperti ini mati: perlahan, lalu dalam pengumuman yang tidak pernah Anda lihat.
Pengumumannya lebih sulit ditemukan daripada gangguannya
Deprecation 2021 dipublikasikan di changelog.unsplash.com, dan itulah URL yang ditautkan
oleh setiap laporan bug sezaman — termasuk laporan Drupal di atas. Tiga pengukuran:
- Endpoint HTTPS-nya rusak.
openssl s_client -connect changelog.unsplash.com:443mengembalikantlsv1 alert internal error— handshake gagal sebelum sertifikat apa pun ditampilkan. Setiap tautan era 2021, yang menggunakanhttps://, karena itu mati di browser. - Lewat HTTP biasa memang redirect, tapi tidak berguna. Mengikuti
http://changelog.unsplash.com/deprecations/2021/11/25/source-deprecation.htmlberakhir, setelah dua lompatan, pada400diunsplash.com/@documentation/changelog/deprecations/2021/11/25/source-deprecation/html— path-nya sudah tertelan oleh rute username milik situs tersebut. - Arsipnya berlubang tepat di titik sunset. Tangkapan Wayback Machine yang terakhir berhasil dari changelog lama adalah 24 Maret 2024; tangkapan pertamanya dari yang baru adalah 23 Agustus 2024. Sunset diumumkan pada 11 Juni 2024 — persis di dalam celah lima bulan itu.
Tak satu pun dari itu adalah konspirasi; ini migrasi CMS biasa. Tapi konsekuensinya nyata, dan itulah alasan artikel ini mengutip kedua entri secara lengkap: catatan primer sebuah deprecation seharusnya bertahan lebih lama daripada hal yang di-deprecate-nya, dan di sini nyaris saja tidak terjadi demikian.
Apa yang benar-benar rusak
Bukan proyek sampingan. Kegagalan di bawah ini adalah entri pelacak isu publik; judul, tanggal, dan statusnya berasal dari API GitHub dan drupal.org.
| Proyek | Isu | Dibuka | Isinya |
|---|---|---|---|
| MUI (Material UI) | #42736 | 24 Jun 2024 | “[docs] Random Unsplash photo URL is no longer functional” — template resmi Sign-in side menyertakan gambar mati. Ditutup tiga hari kemudian. |
| Nextcloud | #115 | 17 Jan 2023 | “Migrate to Unsplash API” — aplikasi background ini dibangun di atas URI Source. Terbuka selama delapan belas bulan, ditutup 16 Juli 2024. |
| sindresorhus/Actions | #248 | 28 Mei 2024 | “Get Unsplash Image: 503 Error” — sebuah Shortcuts action untuk iOS/macOS, rusak dua minggu sebelum sunset diumumkan. |
| Drupal — Gin Login | #3324054 | 28 Nov 2022 | “Unsplash has deprecated source.unsplash.com — this delays reCAPTCHA from loading, preventing users from logging in.” |
Baca kembali baris terakhir itu, karena inilah yang paling perlu diresapi. Sebuah gambar dekoratif di samping formulir login — aset paling jelas non-kritis di halaman itu — merosot menjadi gangguan autentikasi, karena sebuah permintaan pihak ketiga yang lambat menghalangi CAPTCHA yang dibutuhkan formulir login. Tidak ada yang sengaja menulis kode seperti itu. Ini muncul begitu saja dari urutan bagaimana browser memuat sesuatu.
Asisten koding Anda tidak menerima memonya
Inilah bagian yang mengubah gangguan tahun 2024 menjadi masalah tahun 2026.
source.unsplash.com didokumentasikan, ditulis di blog, diajarkan, dan disalin selama
kurang lebih delapan tahun. Semua teks itu ada di dalam data pelatihan model-model yang sekarang
menulis kode starter kita — dan teks tidak kedaluwarsa. Tiga hitungan:
| Pengukuran | Nilai pada 30 Agu 2026 | Bagaimana diukur |
|---|---|---|
File yang mengandung source.unsplash.com |
3.344 | API pencarian kode GitHub, q=source.unsplash.com (hanya kode publik yang terindeks — ini batas bawah, bukan total) |
| Repositori dalam sampel 100 file yang dibuat setelah sunset | 12 dari 77 | Query yang sama, 100 hasil, dideduplikasi menjadi 77 repositori, created_at dibandingkan dengan 11 Jun 2024 |
| …dan repositori dalam sampel itu yang di-push dalam 12 bulan terakhir | 20 dari 77 | Repositori aktif, bukan arsip — termasuk elastic/kibana, yang file demo-nya masih menulis imageUrl: 'https://source.unsplash.com/64x64/?dingo' |
Unduhan bulanan unsplash-source-es6 |
23 | API registry npm — sebuah wrapper untuk layanan yang sudah mati, terakhir dipublikasikan tahun 2022, tapi masih diinstal |
| Postingan Stack Overflow yang menyebutkannya | 1.459 | API Stack Exchange, total dari /search/excerpts |
Bukti paling langsung sama sekali tidak ada di kode aplikasi — melainkan di dalam prompt. Hasil teratas dari pencarian itu adalah sebuah pustaka prompt sistem GPT yang mengandung baris “please use unsplash API( https://source.unsplash.com/1280x720/?<PUT YOUR QUERY HERE>”. Instruksi itu masih disalin ke dalam asisten-asisten baru sampai hari ini. Model tidak memverifikasi URL-nya; ia diberi tahu untuk menggunakannya, dan setiap contoh yang pernah ia lihat sepakat dengan itu.
Jadi kegagalan kode yang dihasilkan ini punya dua penyebab yang independen, dan memperbaiki salah satunya tidak memperbaiki yang lain: data pelatihan yang sudah usang, dan instruksi usang yang ditulis manusia di atasnya. Bagaimanapun juga, gejalanya sama: sekelompok gambar yang tidak pernah termuat:
source.unsplash.com/random/1200x800 # 503 sejak pertengahan 2024 — tidak akan kembali
images.unsplash.com/photo-… # CDN asli, tapi ID yang dihafal mungkin tidak ada
via.placeholder.com/400 # kotak abu-abu, terlanjur masuk produksi
placehold.co/800x600 # kotak abu-abu, memang disengaja
picsum.photos/800/600 # foto asli, tapi tidak berhubungan dengan halaman Anda
/placeholder.png # file yang tidak pernah ditambahkan ke repo
Catatan kaki untuk baris kedua daftar itu: saat menulis ini, via.placeholder.com juga
tidak berhasil menyelesaikan TLS handshake dari jaringan uji kami, dan menjawab 403
lewat HTTP biasa. Periksa dari jaringan Anda sendiri sebelum mempercayainya — fallback yang dipakai
alat-alat ini pun bisa punya cerita gangguannya sendiri.
Hanya yang pertama yang benar-benar rusak. Yang lain lebih buruk dengan cara yang lebih halus: gambarnya termuat, layout-nya terlihat selesai, dan tidak ada yang sadar bahwa halaman itu diilustrasikan dengan sesuatu yang tidak jelas. Dan ini semua tidak spesifik untuk gambar saja — ini bentuk umum dari masalah tersebut. Gambaran sebuah model tentang web adalah sebuah snapshot, dan endpoint, flag CLI, nama paket, serta free tier terus berubah setelah rana kameranya menutup.
Tabel migrasi
Ada tepat tiga tujuan, dan cara jujur untuk menyajikannya adalah dengan apa yang harus Anda korbankan. Pilih dulu kolomnya, baru baca barisnya.
| URL Source lama | A. URL CDN tetaptanpa kunci · tanpa keacakan | B. Unsplash APIkunci · panggilan sisi server | C. Proxy milik Anda sendirikunci tersembunyi · keacakan kembali |
|---|---|---|---|
/random |
images.unsplash.com/photo-… — satu foto yang Anda pilih |
GET /photos/random |
/?w=1600 |
/random/1600x900 |
…?w=1600&h=900&fit=crop |
/photos/random + parameter Imgix pada URL yang dikembalikan |
/?w=1600&h=900&fit=crop |
/1600x900/?apple,desk |
Tidak ada padanan — pilih foto secara manual | /photos/random?query=apple,desk |
/?query=apple,desk&w=1600 |
/featured/1600x900?nature |
Tidak ada padanan | /photos/random?query=nature “featured” tidak punya penerus |
/?query=nature&w=1600 |
/collection/67920491/1600x900 |
Tidak ada padanan | /photos/random?collections=67920491 |
/?collections=67920491&w=1600 |
/user/scottwebb/1600x900 |
Tidak ada padanan | /photos/random?username=scottwebb |
/?username=scottwebb&w=1600 |
/daily |
Pin satu foto, ganti-ganti saat build | Tidak ada padanan — cache sendiri satu foto acak selama 24 jam | Sama, dengan cache di dalam proxy |
Opsi A adalah yang sebenarnya paling banyak dibutuhkan orang. Jika gambarnya bersifat dekoratif — sebuah hero, panel samping login, atau background kartu — Anda sebenarnya tidak pernah perlu foto berbeda di setiap permintaan. Pilih satu, simpan URL CDN-nya, dan halaman berhenti bergantung pada apa pun yang acak:
<img src="https://images.unsplash.com/photo-1506905925346-21bda4d32df4?w=1600&h=900&fit=crop&auto=format"
width="1600" height="900" alt="…">
# Parameter yang resmi didukung: w, h, crop, fit, fm, auto=format, q, dpr.
# Simpan parameter ixid apa pun yang diberikan API — itulah yang melaporkan tampilan (view).
Opsi B adalah jalur resmi, dan ia memindahkan panggilan ke sisi server, karena
Client-ID di JavaScript front-end adalah kredensial yang terpublikasi. Perhatikan dua
aturan yang sering membuat orang tersandung: collections/topics tidak
bisa digabungkan dengan query dalam permintaan yang sama, dan count
(maks 30) mengubah bentuk respons menjadi sebuah array bahkan saat nilainya 1.
curl "https://api.unsplash.com/photos/random?query=nature&orientation=landscape" \
-H "Authorization: Client-ID YOUR_ACCESS_KEY" \
-H "Accept-Version: v1"
# → JSON. Gambarnya ada di .urls.regular / .urls.raw (tambahkan w/h/fit sendiri).
# → X-Ratelimit-Limit: 1000 X-Ratelimit-Remaining: 999
Opsi C: membangun ulang Source, dalam sekitar empat puluh baris
Jika yang Anda kehilangan benar-benar adalah perilakunya — sebuah URL tanpa kunci yang mengembalikan
foto berbeda setiap saat, bisa dipakai langsung dari tag <img>, di field CMS,
atau di situs statis yang tidak punya server — maka Anda harus menjalankan endpoint itu sendiri.
Ini adalah satu worker kecil di depan API, dan tiga hal yang membuatnya bertahan menghadapi
produksi adalah cache-nya, pemeriksaan referrer, dan meneruskan sisa query string ke CDN.
// Cloudflare Workers. Di tempat lain (Deno Deploy, Val Town…) bentuknya sama,
// tapi buka cache bernama dengan caches.open() alih-alih caches.default.
// UNSPLASH_KEY tetap di sisi server. Pemanggil tidak pernah melihatnya.
const ALLOWED = ["example.com", "www.example.com"]; // hanya domain Anda
const API_PARAMS = ["query", "collections", "topics", "username", "orientation"];
const TTL = 60; // detik — melindungi kuota per jam
const host = (value) => { try { return new URL(value).hostname; } catch { return null; } };
export default {
async fetch(req, env, ctx) {
// 0. Hanya GET: Cache API menolak menyimpan apa pun selain itu, dan sebuah
// endpoint gambar tidak punya verb lain untuk dijawab.
if (req.method !== "GET")
return new Response("Method not allowed", { status: 405 });
const url = new URL(req.url);
// 1. Hanya halaman Anda sendiri yang boleh menyematkannya — endpoint foto acak
// publik di internet terbuka hanya akan menghabiskan rate limit milik orang lain.
const ref = req.headers.get("referer"); // sering tidak ada pada banyak klien yang sah
if (ref && !ALLOWED.includes(host(ref)))
return new Response("Forbidden", { status: 403 });
// 2. Cache per kombinasi parameter, sehingga halaman dengan 12 gambar
// hanya butuh satu panggilan API per menit, bukan dua belas per render.
const cache = caches.default;
const hit = await cache.match(req);
if (hit) return hit;
// 3. Minta API resmi untuk sebuah foto acak.
const api = new URL("https://api.unsplash.com/photos/random");
for (const p of API_PARAMS)
if (url.searchParams.has(p)) api.searchParams.set(p, url.searchParams.get(p));
const r = await fetch(api, { headers: {
Authorization: "Client-ID " + env.UNSPLASH_KEY,
"Accept-Version": "v1",
}});
// 403 di sini biasanya berarti kuota per jam, bukan kunci yang salah — naikkan TTL, jangan panik.
if (!r.ok) return new Response("Upstream " + r.status, { status: 502 });
const photo = await r.json();
// 4. Bangun ulang URL gambar: simpan ixid, tambahkan parameter ukuran dari pemanggil.
const img = new URL(photo.urls.raw); // .raw sudah membawa ixid
for (const [k, v] of url.searchParams)
if (!API_PARAMS.includes(k)) img.searchParams.set(k, v); // w, h, fit, q…
const res = new Response(null, { status: 302, headers: {
Location: img.toString(),
"Cache-Control": "public, max-age=" + TTL,
// Kredit ikut bersama redirect; nilai header harus ASCII, karenanya di-encode.
"X-Photo-Credit": encodeURIComponent(photo.user.name + " on Unsplash"),
"X-Photo-Link": photo.links.html,
}});
ctx.waitUntil(cache.put(req, res.clone()));
return res;
},
};
Migrasi sebuah URL kemudian menjadi sekadar cari-dan-ganti, dan itulah yang membuat opsi ini layak dengan dua puluh menit usaha:
- https://source.unsplash.com/collection/67920491/1600x900
+ https://img.example.com/?collections=67920491&w=1600&h=900&fit=crop
Dua catatan desain, yang keduanya pernah membuat seseorang mengalami sore hari yang buruk sebelum
akhirnya dituliskan. Redirect (302) alih-alih mem-proxy byte-nya membuat Anda tidak
perlu menanggung bandwidth dan tetap membuat view-nya terhitung di CDN Unsplash, yang
memang diminta oleh panduannya. Dan pemeriksaan Referer sengaja dibuat longgar saat
header itu tidak ada — banyak klien sah yang menghapusnya — sambil tetap mencegah kasus jelas
di mana endpoint Anda berubah menjadi API gambar gratis milik orang lain.
Aturan yang Anda warisi begitu memakai API
Source tidak punya aturan karena tidak punya akun. API-nya punya lima aturan yang mengubah cara Anda mendesain sistem, semuanya dari dokumentasi terkini:
- Rate limit dihitung per jam, dan kecil di awal. 50 request/jam
dalam mode demo; 1.000/jam setelah aplikasi Anda disetujui untuk produksi. Hanya
panggilan ke
api.unsplash.comyang dihitung — permintaan gambar keimages.unsplash.comtidak dihitung. BacaX-Ratelimit-Remainingdi setiap respons. - Hotlinking wajib, bukan sekadar diizinkan. Unsplash mensyaratkan URL gambar yang dikembalikan API disematkan langsung, agar tampilan foto bisa diatribusikan ke fotografernya. Meng-mirror file itu ke CDN Anda sendiri adalah satu optimisasi yang tidak bebas Anda lakukan.
- Pertahankan parameter
ixid. Mengubah ukuran dan memotong URL yang dikembalikan itu wajar; menghapus parameter yang mengidentifikasi aplikasi Anda tidak. - Atribusi dan pelacakan unduhan adalah bagian dari kesepakatan — fotografer dan Unsplash mendapat kredit, dan sebuah “download” dilaporkan lewat endpoint download milik foto tersebut saat pengguna mengambil filenya, yang merupakan sebuah event yang harus Anda picu sendiri.
- Produk yang didistribusikan butuh pendaftaran klien dinamis. Jika Anda merilis sebuah plugin, tema, atau CMS self-hosted, satu kunci bersama sekaligus melanggar kebijakan dan menjadi satu titik kegagalan tunggal; API-nya punya alur pendaftaran khusus untuk kasus tersebut.
Ini saat yang tepat untuk jujur soal cakupan: jika Anda tetap harus menyambungkan API dan kunci, pilihan API gambar mana yang dipakai tiba-tiba jadi terbuka, dan itu layak dipikirkan lima menit sebelum Anda menulis client-nya. Kami membandingkan yang gratis — kuota, aturan, perilaku pencarian, dan bentuk respons — di perbandingan API stock photo gratis.
Jika Anda hanya ingin placeholder, katakan saja
Sebagian besar pemakaian Source sebenarnya bukan soal Unsplash sama sekali. Melainkan “taruh sesuatu yang berbentuk gambar di sini sementara saya membangun layout-nya”. Untuk itu, layanan tanpa kunci masih ada dan merupakan jawaban yang tepat:
| Layanan | Kunci? | Yang Anda dapat | Batasannya |
|---|---|---|---|
| Lorem Picsum | Tidak | Foto asli: picsum.photos/800/600, yang stabil dengan /id/237/… atau /seed/xxx/…, plus ?grayscale dan ?blur=1..10. Endpoint /v2/list-nya mencantumkan kredit halaman Unsplash dan penulis setiap foto. |
Tidak ada penargetan subjek sama sekali. Fotonya tidak akan berhubungan dengan halaman Anda. |
| placehold.co | Tidak | Persegi panjang berlabel dengan ukuran berapa pun — pengisi wireframe yang jujur. | Ini kotak abu-abu, dan terlihat seperti kotak abu-abu di screenshot yang dibagikan ke klien. |
| Openverse | Tidak | Katalog berlisensi terbuka dengan API publik, dikelola oleh WordPress.org. | Pencocokan kata kunci, dan lisensinya berbeda-beda per item — Anda harus membacanya. |
Perbedaan yang penting: placeholder secara definisi bersifat sementara. Jika gambarnya bertahan sampai produksi, itu bukan placeholder lagi — itu ilustrasi yang tidak dipilih siapa pun, dan pembaca bisa merasakannya.
Satu kunci alih-alih tiga
Inilah bagian migrasi yang tidak direncanakan siapa pun: orang yang meninggalkan Source jarang
mendarat di satu API saja. Sebuah halaman butuh hero, dua gambar section, dan sesuatu
untuk grid kartu, dan jawaban jujurnya biasanya Unsplash ditambah Pexels ditambah
Pixabay — tiga pendaftaran, tiga skema autentikasi, tiga bentuk JSON, tiga model paginasi, dan
tiga set aturan atribusi, semua hanya untuk mengisi tag <img> yang sama.
Pekerjaan integrasi itulah tagihan sebenarnya dari hilangnya sebuah URL tanpa kunci, dan itu
datang berminggu-minggu setelah gangguan yang menyebabkannya.
Meringkas semua itu menjadi satu integrasi adalah alasan kami membangun Pexafy: satu kunci untuk 9 pustaka berlisensi gratis dalam satu skema, dengan pencarian semantik tingkat kalimat — sehingga deskripsi lengkap seperti “a cracked phone screen on a wooden desk, shot from above” menghasilkan hasil yang diurutkan, bukan kosong. Dua batasan, dinyatakan dengan jelas, karena seluruh artikel ini memang soal tidak ingin terkejut dua kali: layanan ini butuh kunci, jadi ia tidak mengembalikan apa yang dulu dimiliki Source — ia berada di kategori yang sama dengan Unsplash API resmi di atas; dan ia menyediakan fotografi berlisensi gratis, bukan gambar editorial atau brand.
Bagian yang benar-benar baru ditujukan untuk asisten-asisten di atas: sebuah
server MCP di mcp.pexafy.com/mcp berarti sebuah model yang tadinya akan mengucapkan
ulang sebuah URL gambar dari hafalan sekarang bisa mencari katalog nyata dan mengembalikan foto
yang benar-benar ada, lengkap dengan baris kreditnya. Itu jawaban yang lebih baik untuk URL mati
yang ditulis mesin dibanding aturan lint mana pun, dan alasannya dijabarkan di
infrastruktur
pencarian gambar untuk agen AI.
Audit aset Anda dalam sepuluh menit
Apa pun tujuan migrasi Anda, lakukan bagian ini dulu — Anda tidak bisa memperbaiki URL yang belum Anda temukan. Source hanyalah contoh hari ini; tiga langkah yang sama berlaku untuk setiap aset eksternal yang Anda sematkan.
# 1. Semua yang ada di repo, termasuk dokumentasi, tes, fixture, dan README.
grep -rn --binary-files=without-match \
-e "source.unsplash.com" -e "via.placeholder.com" -e "/placeholder.png" .
# 2. Semua yang tersimpan di database — body CMS adalah tempat ini paling lama bersembunyi.
psql -c "SELECT id FROM posts WHERE body LIKE '%source.unsplash.com%'"
# 3. Semua yang benar-benar diminta situs yang sudah di-build: crawl dan daftar kegagalannya.
# Cocokkan atributnya, bukan ekstensi file — URL gambar jarang berakhiran .jpg.
grep -rhoE 'src="[^"]+"' dist/ \
| cut -d'"' -f2 | grep -E '^https?://' | sort -u \
| xargs -P8 -I{} curl -s -o /dev/null -w "%{http_code} {}\n" {} \
| grep -v "^200"
# 503 https://source.unsplash.com/random/1200x800 ← inilah yang Anda cari
Lalu putuskan, sekali saja, seberapa besar biaya yang boleh ditanggung akibat gambar eksternal. Empat aturan yang tetap berlaku saat penutupan berikutnya terjadi, siapa pun penyebabnya:
- Ambil gambar saat build, bukan saat request. Gambar yang di-resolve selama proses build gagal di CI, di depan seorang developer, alih-alih pada jam 3 pagi di depan pengguna.
- Jangan pernah biarkan aset dekoratif menghalangi jalur kritis. Jangan
preload apa pun yang eksternal di atas formulir login; beri setiap
<img>pihak ketiga sebuah fallbackonerrorsertawidth/heighteksplisit sehingga kegagalan hanya berujung kotak kosong, bukan pergeseran layout atau script yang macet. - Tambahkan pemeriksaan ini ke CI. Langkah 3 di atas, dijalankan pada output hasil build Anda, mengubah “akhirnya ada yang sadar” menjadi build yang merah. Ini satu-satunya langkah yang mencegah masalah ini terulang.
- Anggarkan dependensi eksternal Anda seperti dependensi lainnya. Tuliskan host mana saja yang boleh diandalkan halaman Anda dan apa yang terjadi saat masing-masing down. URL yang tidak perlu Anda daftarkan tetaplah sebuah dependensi — Source membuktikan bahwa itu hanyalah dependensi yang tidak dimiliki siapa pun.
Referensi & catatan kaki
1 Setiap kode status, hitungan, dan kalimat kutipan dalam artikel
ini diambil dari sumber primernya pada 30 Agustus 2026. Kode status
HTTP diambil dengan curl terhadap setiap pola URL; semuanya mengembalikan
503 dengan server: Heroku dan body yang menyematkan
herokucdn.com/error-pages/application-error.html. Resolusi DNS dikonfirmasi pada
hari yang sama (sebuah CNAME ke host herokudns.com).
2 Kedua entri changelog dikutip verbatim dari
unsplash.com/documentation/changelog. Redaksi kebijakan deprecation (pemberitahuan
3 minggu, header Warning, dan pengecualian untuk endpoint yang tidak
didokumentasikan secara publik) berasal dari unsplash.com/documentation, hari
yang sama.
3 Kegagalan TLS direproduksi dengan
openssl s_client -connect changelog.unsplash.com:443 (tlsv1 alert internal
error). Rantai redirect diikuti dengan curl -L. Celah arsip diambil dari
Wayback CDX API: tangkapan 200 terakhir dari changelog.unsplash.com
pada 20240324, tangkapan pertama dari unsplash.com/documentation/changelog pada
20240823.
4 Judul isu, tanggal dibuat dan ditutup dibaca dari API REST
GitHub (mui/material-ui#42736, nextcloud/unsplash#115,
sindresorhus/Actions#248) dan dari API JSON drupal.org untuk isu
gin_login nomor 3324054, yang isinya melaporkan “I get always a Heroku
application error” pada November 2022.
5 Hitungan: API pencarian kode GitHub
(3.344 file; sampel 100 hasil dideduplikasi menjadi 77 repositori, di mana 12
dibuat setelah 11 Juni 2024 dan 20 telah di-push dalam 12 bulan sebelumnya); API
unduhan registry npm (unsplash-source-es6, 23 unduhan selama 30 hari sebelumnya);
Stack Exchange /search/excerpts (1.459 postingan). Pencarian kode
hanya mencakup repositori publik yang terindeks, jadi setiap angka adalah batas bawah.
Sumber primer: Unsplash API changelog · Unsplash API documentation · Unsplash attribution guideline · Unsplash status · MUI #42736 · Nextcloud #115 · sindresorhus/Actions #248 · Drupal Gin Login #3324054 · Lorem Picsum · Openverse · Pexafy API & MCP docs.
Pertanyaan yang sering diajukan
Apakah source.unsplash.com sedang down, atau sudah dimatikan secara permanen?
/random, /1600x900/?query, /collection/…, /daily) kini mengembalikan HTTP 503 dengan halaman generik Application Error milik Heroku. Hostname-nya masih bisa di-resolve, sehingga kegagalannya muncul sebagai gambar rusak, bukan error jaringan.Apa pengganti langsung untuk source.unsplash.com/random?
images.unsplash.com/photo-…?w=1600&h=900&fit=crop — tidak memerlukan key tetapi selalu mengembalikan foto yang sama, yang sebenarnya sudah cukup untuk kebanyakan kebutuhan dekoratif. API resmi, GET https://api.unsplash.com/photos/random dengan header Authorization: Client-ID, mengembalikan keacakan tetapi harus dipanggil dari sisi server. Proxy kecil milik Anda sendiri di depan endpoint tersebut adalah satu-satunya opsi yang mengembalikan URL tanpa key yang bisa langsung dipasang di tag <img>.Mengapa alat AI coding masih menghasilkan URL source.unsplash.com pada 2026?
Apakah saya masih bisa mendapatkan foto acak dari Unsplash tanpa API key?
/photos/random, yang mewajibkan Client-ID. Dua rute tanpa key yang tersedia adalah proxy yang Anda hosting sendiri, di mana key tetap berada di sisi server dan URL publiknya terlihat seperti URL lama, atau layanan placeholder pihak ketiga seperti Lorem Picsum (picsum.photos/800/600), yang menyajikan foto asli tanpa key tetapi juga tanpa penargetan subjek sama sekali.Apakah Unsplash API mengizinkan pengunduhan dan self-hosting gambar?
ixid saat mengubah ukuran atau memotong URL, cantumkan kredit untuk fotografer dan Unsplash, serta panggil endpoint download foto saat pengguna mengunduh file tersebut. Menyalin file-file tersebut ke CDN milik Anda sendiri adalah satu optimisasi yang tidak boleh Anda lakukan.Mengapa pemberitahuan deprecation tahun 2021 tidak melindungi pengguna lama?
Warning — berlaku untuk field dan endpoint yang didokumentasikan secara publik, dan paragraf yang sama menyatakan bahwa apa pun yang tidak terdokumentasi bisa berubah tanpa peringatan. Source tidak pernah menjadi endpoint API yang terdokumentasi, sehingga berada di luar kebijakan yang seharusnya melindunginya.Bagaimana cara menemukan semua URL source.unsplash.com yang sudah mati di proyek saya?
grep -rn "source.unsplash.com" . — karena URL semacam ini paling bertahan lama di kode contoh. Query database, karena isi artikel CMS adalah tempat URL ini sering bersembunyi (WHERE body LIKE '%source.unsplash.com%'). Lalu crawl output hasil build Anda: ekstrak semua URL gambar dan minta masing-masing, lalu daftar apa pun yang bukan 200. Tambahkan tahap terakhir ini ke CI agar aset pihak ketiga yang sudah mati membuat build gagal, bukan malah membuat halaman gagal.