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.

Foto hitam-putih sebuah smartphone dengan layar retak yang tergeletak di atas permukaan kayu pucat, dengan logo Unsplash tampak di layar yang rusak.
Foto via Unsplash

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:

terminal
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/randomFoto acak, ukuran apa pun503
source.unsplash.com/random/1600x900Foto acak, dipotong sesuai ukuran503
source.unsplash.com/1600x900/?apple,deskFoto acak yang cocok dengan kata kunci pencarian503
source.unsplash.com/featured/1600x900?natureFoto featured secara acak503
source.unsplash.com/collection/190727/800x600Foto acak dari sebuah koleksi503
source.unsplash.com/user/scottwebb/1600x900Foto acak dari satu fotografer503
source.unsplash.com/dailyFoto hari ini503

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:

  1. Endpoint HTTPS-nya rusak. openssl s_client -connect changelog.unsplash.com:443 mengembalikan tlsv1 alert internal error — handshake gagal sebelum sertifikat apa pun ditampilkan. Setiap tautan era 2021, yang menggunakan https://, karena itu mati di browser.
  2. Lewat HTTP biasa memang redirect, tapi tidak berguna. Mengikuti http://changelog.unsplash.com/deprecations/2021/11/25/source-deprecation.html berakhir, setelah dua lompatan, pada 400 di unsplash.com/@documentation/changelog/deprecations/2021/11/25/source-deprecation/html — path-nya sudah tertelan oleh rute username milik situs tersebut.
  3. 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:

PengukuranNilai pada 30 Agu 2026Bagaimana 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:

pola gambar mati yang layak di-grep
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:

URL Unsplash tetap yang bisa diubah ukurannya — tanpa kunci, tanpa panggilan API
<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.

pengganti resmi untuk /random
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.

worker.js — endpoint bergaya Source tanpa kunci di atas /photos/random
// 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:

penggantian satu-lawan-satu
- 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.com yang dihitung — permintaan gambar ke images.unsplash.com tidak dihitung. Baca X-Ratelimit-Remaining di 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:

LayananKunci?Yang Anda dapatBatasannya
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.

temukan setiap referensi mati, lalu cegah kembalinya
# 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:

  1. 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.
  2. Jangan pernah biarkan aset dekoratif menghalangi jalur kritis. Jangan preload apa pun yang eksternal di atas formulir login; beri setiap <img> pihak ketiga sebuah fallback onerror serta width/height eksplisit sehingga kegagalan hanya berujung kotak kosong, bukan pergeseran layout atau script yang macet.
  3. 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.
  4. 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.

Pertanyaan yang sering diajukan

Apakah source.unsplash.com sedang down, atau sudah dimatikan secara permanen?
Permanen. Unsplash mengumumkan penghentian layanan pada 11 Juni 2024 — “we will first wind down by disabling the search feature, and in the coming weeks turn off the application entirely” — setelah sebelumnya mendeprekasi layanan ini pada 25 November 2021. Setiap pola (/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?
Tidak ada pengganti tanpa API key yang bisa langsung dipakai, dan itu bagian yang sebaiknya diterima sejak awal. Ada tiga pengganti. URL CDN tetap — 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?
Karena URL ini didokumentasikan, diajarkan, dan disalin selama kurang lebih delapan tahun, dan korpus pelatihan tidak ikut kedaluwarsa saat sebuah layanan mati. Diukur pada 30 Agustus 2026: pencarian kode GitHub masih menemukan 3.344 file yang mengandungnya, dan dari sampel 100 file, 12 dari 77 repository dibuat setelah layanan ini dimatikan. Kumpulan prompt buatan manusia pun mengulangi instruksi yang sama — salah satu prompt GPT yang banyak disalin masih menyuruh model untuk “use unsplash API( https://source.unsplash.com/1280x720/?… )”. Perlakukan setiap URL gambar yang ditulis oleh model sebagai belum terverifikasi dan periksa status code-nya di CI.
Apakah saya masih bisa mendapatkan foto acak dari Unsplash tanpa API key?
Tidak langsung dari Unsplash — pemilihan acak kini berada di balik /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?
Tidak. Berbeda dari kebanyakan API, Unsplash mewajibkan hotlinking: URL gambar yang dikembalikan API harus disematkan langsung, agar tampilan foto tetap terhitung untuk fotografernya. Ada tiga kewajiban yang menyertainya — pertahankan parameter 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?
Karena pemberitahuan dan kebijakannya sebenarnya tidak membahas hal yang sama. Entri changelog tanggal 25 November 2021 menjanjikan bahwa “existing uses will continue to work” dan tidak memberikan tanggal berakhir. Kebijakan deprecation resmi Unsplash — minimal tiga minggu pemberitahuan plus header 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?
Tiga tahap, sepuluh menit. Grep repository termasuk dokumentasi, test, fixture, dan README — 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.

Berhenti memburu kata kunci. Deskripsikan apa yang Anda maksud.

Cari 9M+ gambar bebas pakai berdasarkan makna — dalam bahasa apa pun, dalam kurang dari 100 md.