source.unsplash.com è sparito: il post-mortem e tutti i modi per sostituirlo

Deprecato nel 2021 con la promessa che “gli usi esistenti continueranno a funzionare”, spento a giugno 2024, e ancora oggi scritto in codice nuovo. Il post-mortem misurato — e le tre alternative, con il proxy che restituisce la casualità senza chiave.

Condividi
Una fotografia in bianco e nero di uno smartphone con lo schermo incrinato appoggiato su una superficie di legno chiaro, con il logo Unsplash visibile sul display danneggiato.
Foto via Unsplash

Un servizio di foto stock ha spento un sottodominio, e due anni dopo continua a rompere siti di documentazione, schermate di login, esercizi di corsi e codice generato di recente. Questo è un post-mortem di un URL — cosa faceva, cosa lo ha ucciso e cosa mettere al suo posto — più uno sguardo misurato sulla parte più strana della storia: le macchine che scrivono il nostro codice non si sono accorte che è sparito.

Le risposte HTTP, le due voci di changelog citate parola per parola, i limiti API, i tracker delle issue dei progetti che si sono rotti e i conteggi da GitHub, npm e Stack Overflow provengono tutti da fonti primarie, con il metodo per ciascuna riportato nelle note a piè di pagina. Se vuoi solo la soluzione, vai direttamente a la tabella di migrazione.

Cosa ottieni oggi, se lo richiedi ancora

Un comando, nessuna chiave, riproducibile da qualsiasi macchina:

terminale
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: un iframe che punta a herokucdn.com/error-pages/application-error.html

Non è un fallimento DNS. source.unsplash.com risolve ancora — è un CNAME verso un host herokudns.com — quindi alla richiesta viene risposto, solo non da un'applicazione. Questo dettaglio conta più di quanto sembri: un browser che riceve un 503 veloce con un corpo HTML disegna un segnaposto di immagine rotta, e qualsiasi codice che legge response.ok o un gestore onerror che non hai mai scritto imbocca il percorso di fallimento che non hai mai testato.

Pattern URL Cosa restituiva prima Oggi
source.unsplash.com/randomUna foto casuale, di qualsiasi dimensione503
source.unsplash.com/random/1600x900Una foto casuale, ritagliata alla dimensione503
source.unsplash.com/1600x900/?apple,deskUna foto casuale corrispondente ai termini di ricerca503
source.unsplash.com/featured/1600x900?natureUna foto casuale in evidenza503
source.unsplash.com/collection/190727/800x600Una foto casuale da una collezione503
source.unsplash.com/user/scottwebb/1600x900Una foto casuale da un fotografo specifico503
source.unsplash.com/dailyLa foto del giorno503

Verificato individualmente con curl -o /dev/null -w "%{http_code}". La funzione di ricerca è stata smantellata per prima, come annunciato; oggi l'intera applicazione è spenta, quindi la distinzione non esiste più.

Tre anni tra “deprecato” e “spento”

Entrambi gli annunci sono ancora leggibili, in un unico posto, su unsplash.com/documentation/changelog. Citati per intero, perché la formulazione è tutta la storia:

25 novembre 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 giugno 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.”

Leggendoli in sequenza, la modalità di fallimento è evidente. L'avviso del 2021 conteneva una promessa (existing uses will continue to work) e nessuna data. Uno sviluppatore che lo lesse nel 2021 aveva ogni ragione per lasciare invariato il codice funzionante; uno sviluppatore arrivato nel 2022 non lo ha mai letto affatto. L'avviso del 2024 diede “le prossime settimane”, tre anni dopo, su una pagina che nessuno aveva salvato nei preferiti.

Unsplash pubblica effettivamente una politica di deprecazione, ed è ragionevole — la documentazione afferma che per i campi ed endpoint pubblicamente documentati, i cambiamenti vengono annunciati sul changelog con almeno 3 settimane di preavviso, e gli endpoint restituiscono un header Warning durante il periodo di deprecazione. Lo stesso paragrafo contiene la frase che spiega perché nulla di tutto ciò abbia protetto Source: “For any non-publicly documented fields or endpoints, we may make changes to these with no warning.” Source non è mai stato un endpoint dell'API documentata. Si trovava fuori dalla politica che lo avrebbe altrimenti coperto.

  • La lezione pratica non è “Unsplash è stata negligente”. È che un URL che si può usare senza leggere alcuna documentazione è un URL la cui politica di deprecazione, allo stesso modo, non hai letto.
  • La rottura ha preceduto l'annuncio. Una issue Drupal aperta il 28 novembre 2022 già riporta “I get always a Heroku application error”, diciotto mesi prima della voce di dismissione. Il fallimento intermittente è il modo in cui questi servizi muoiono: lentamente, e poi in un annuncio che non vedi mai.

L'annuncio è più difficile da trovare del disservizio

La deprecazione del 2021 fu pubblicata su changelog.unsplash.com, ed è l'URL a cui rimanda ogni segnalazione di bug dell'epoca — inclusa quella Drupal citata sopra. Tre misurazioni:

  1. L'endpoint HTTPS è rotto. openssl s_client -connect changelog.unsplash.com:443 restituisce tlsv1 alert internal error — l'handshake fallisce prima che venga presentato qualsiasi certificato. Ogni link dell'epoca 2021, che era in https://, è quindi morto in un browser.
  2. Su HTTP semplice reindirizza, ma non in modo utile. Seguendo http://changelog.unsplash.com/deprecations/2021/11/25/source-deprecation.html si finisce, due salti dopo, su un 400 su unsplash.com/@documentation/changelog/deprecations/2021/11/25/source-deprecation/html — il percorso è stato inghiottito dalla route dei nomi utente del sito.
  3. L'archivio ha un buco proprio dove si trova la dismissione. L'ultima cattura riuscita della Wayback Machine del vecchio changelog è del 24 marzo 2024; la prima cattura di quello nuovo è del 23 agosto 2024. La dismissione fu annunciata l' 11 giugno 2024 — dentro quel divario di cinque mesi.

Nulla di tutto ciò è una cospirazione; è una normale migrazione di CMS. Ma la conseguenza è reale, ed è la ragione per cui questo articolo cita entrambe le voci per intero: il registro primario di una deprecazione dovrebbe sopravvivere alla cosa che ha deprecato, e qui è quasi mancato di farlo.

Cosa si è realmente rotto

Non progetti personali. I fallimenti qui sotto sono voci pubbliche di issue tracker; i titoli, le date e gli stati provengono dalle API di GitHub e drupal.org.

Progetto Issue Aperta il Cosa dice
MUI (Material UI) #42736 24 giu 2024 “[docs] Random Unsplash photo URL is no longer functional” — il template ufficiale Sign-in side distribuiva un'immagine morta. Chiusa tre giorni dopo.
Nextcloud #115 17 gen 2023 “Migrate to Unsplash API” — l'app di sfondo era costruita su URI di Source. Aperta per diciotto mesi, chiusa il 16 luglio 2024.
sindresorhus/Actions #248 28 mag 2024 “Get Unsplash Image: 503 Error” — un'azione Shortcuts iOS/macOS, rotta due settimane prima che la dismissione fosse annunciata.
Drupal — Gin Login #3324054 28 nov 2022 “Unsplash has deprecated source.unsplash.com — this delays reCAPTCHA from loading, preventing users from logging in.”

Rileggi quell'ultima riga, perché è quella che vale la pena interiorizzare. Un'immagine decorativa accanto a un form di login — la risorsa più ovviamente non critica della pagina — è degenerata in un blocco dell'autenticazione, perché una richiesta di terze parti lenta si trovava davanti al CAPTCHA di cui il form di login aveva bisogno. Nessuno lo ha scritto in questo modo. È emerso dall'ordine in cui un browser carica le cose.

Il tuo assistente di codice non ha ricevuto la comunicazione

Ecco la parte che trasforma un disservizio del 2024 in un problema del 2026. source.unsplash.com è stato documentato, discusso in blog, insegnato e copiato per circa otto anni. Tutto quel testo è nei dati di addestramento dei modelli che oggi scrivono il nostro codice di partenza — e il testo non scade. Tre conteggi:

MisurazioneValore al 30 ago 2026Come è stata rilevata
File contenenti source.unsplash.com 3.344 API di ricerca codice GitHub, q=source.unsplash.com (solo codice pubblico indicizzato — un minimo, non un totale)
Repository in un campione di 100 file creati dopo la dismissione 12 su 77 Stessa query, 100 risultati, deduplicati a 77 repository, created_at confrontato con l'11 giu 2024
…e repository in quel campione con push negli ultimi 12 mesi 20 su 77 Repository attivi, non archivi — incluso elastic/kibana, il cui file demo riporta ancora imageUrl: 'https://source.unsplash.com/64x64/?dingo'
Download mensili di unsplash-source-es6 23 API del registro npm — un wrapper per un servizio morto, pubblicato l'ultima volta nel 2022, ancora installato
Post su Stack Overflow che lo menzionano 1.459 API Stack Exchange, totale /search/excerpts

La prova più diretta non è nel codice applicativo — è nei prompt. Il risultato principale per quella ricerca è una libreria di prompt di sistema GPT contenente la riga “please use unsplash API( https://source.unsplash.com/1280x720/?<PUT YOUR QUERY HERE>”. Quella istruzione viene ancora copiata in nuovi assistenti oggi. Il modello non verifica l'URL; gli è stato detto di usarlo, e ogni esempio che ha mai visto era concorde.

Quindi il fallimento del codice generato ha due cause indipendenti, e risolverne una non risolve l'altra: dati di addestramento obsoleti, e istruzioni obsolete scritte da esseri umani sopra di essi. In entrambi i casi, il sintomo è la stessa famiglia di immagini che non si caricano mai:

i pattern di immagini morte da cercare con grep
source.unsplash.com/random/1200x800   # 503 da metà 2024 — non torna mai
images.unsplash.com/photo-…           # CDN reale, ma gli ID memorizzati potrebbero non esistere
via.placeholder.com/400               # rettangolo grigio, finito in produzione
placehold.co/800x600                  # rettangolo grigio, di proposito
picsum.photos/800/600                 # una foto reale, non correlata alla tua pagina
/placeholder.png                      # un file che non è mai stato aggiunto al repo

Una nota sulla seconda riga di quell'elenco: mentre scrivevamo questo articolo, via.placeholder.com non riusciva a completare un handshake TLS nemmeno dalla nostra rete di test, e rispondeva con 403 su HTTP semplice. Verificalo dalla tua rete prima di fidartene — il fallback a cui questi strumenti ricorrono può avere una propria storia di disservizio.

Solo il primo è rotto. Gli altri sono peggio in modo più sottile: si caricano, il layout sembra finito, e nessuno nota che la pagina è illustrata con niente in particolare. E nulla di tutto ciò è specifico delle immagini — è la forma generale del problema. La visione del web di un modello è un'istantanea, ed endpoint, flag CLI, nomi di pacchetti e piani gratuiti continuano a cambiare dopo che l'otturatore si chiude.

La tabella di migrazione

Ci sono esattamente tre destinazioni, e il modo onesto di presentarle è mostrare cosa si rinuncia. Scegli prima la colonna, poi leggi la tua riga.

Vecchio URL Source A. URL CDN fissonessuna chiave · nessuna casualità B. API Unsplashchiave · chiamata lato server C. Un proxy tuochiave nascosta · casualità restituita
/random images.unsplash.com/photo-… — una foto che hai scelto GET /photos/random /?w=1600
/random/1600x900 …?w=1600&h=900&fit=crop /photos/random + parametri Imgix sull'URL restituito /?w=1600&h=900&fit=crop
/1600x900/?apple,desk Nessun equivalente — scegli una foto a mano /photos/random?query=apple,desk /?query=apple,desk&w=1600
/featured/1600x900?nature Nessun equivalente /photos/random?query=nature “featured” non ha un successore /?query=nature&w=1600
/collection/67920491/1600x900 Nessun equivalente /photos/random?collections=67920491 /?collections=67920491&w=1600
/user/scottwebb/1600x900 Nessun equivalente /photos/random?username=scottwebb /?username=scottwebb&w=1600
/daily Fissa una foto, ruotala nella tua build Nessun equivalente — metti in cache tu una foto casuale per 24 h Stesso, con la cache nel proxy

L'opzione A è quella che la maggior parte delle persone in realtà vuole. Se l'immagine era decorativa — un hero, un pannello laterale di login, uno sfondo per una card — non hai mai avuto bisogno di una foto diversa a ogni richiesta. Scegline una, tieni l'URL della CDN, e la pagina smette di dipendere da qualcosa di casuale:

un URL Unsplash fisso e ridimensionabile — nessuna chiave, nessuna chiamata API
<img src="https://images.unsplash.com/photo-1506905925346-21bda4d32df4?w=1600&h=900&fit=crop&auto=format"
     width="1600" height="900" alt="…">
# Parametri ufficialmente supportati: w, h, crop, fit, fm, auto=format, q, dpr.
# Mantieni ogni parametro ixid fornito dall'API — è ciò che riporta la visualizzazione.

L'opzione B è il percorso ufficiale, e sposta la chiamata lato server, perché un Client-ID nel JavaScript front-end è una credenziale pubblicata. Nota le due regole che tendono a far inciampare: collections/topics non possono essere combinati con query nella stessa richiesta, e count (massimo 30) cambia la forma della risposta in un array anche quando vale 1.

il sostituto ufficiale di /random
curl "https://api.unsplash.com/photos/random?query=nature&orientation=landscape" \
  -H "Authorization: Client-ID YOUR_ACCESS_KEY" \
  -H "Accept-Version: v1"

# → JSON. L'immagine si trova in .urls.regular / .urls.raw (aggiungi tu w/h/fit).
# → X-Ratelimit-Limit: 1000   X-Ratelimit-Remaining: 999

Opzione C: ricostruire Source, in circa quaranta righe

Se ciò che hai perso era davvero il comportamento — un URL senza chiave che restituisce una foto diversa ogni volta, utilizzabile direttamente da un tag <img>, in un campo CMS, o in un sito statico dove non c'è un server — allora devi eseguire quell'endpoint tu stesso. È un piccolo worker davanti all'API, e le tre cose che lo fanno sopravvivere al contatto con la produzione sono la cache, il controllo del referrer, e il passaggio del resto della stringa di query alla CDN.

worker.js — un endpoint senza chiave in stile Source sopra /photos/random
// Cloudflare Workers. Altrove (Deno Deploy, Val Town…) la forma è la stessa,
// ma apri una cache con nome tramite caches.open() invece di caches.default.
// UNSPLASH_KEY resta lato server. Chi chiama non la vede mai.
const ALLOWED = ["example.com", "www.example.com"];   // solo i tuoi domini
const API_PARAMS = ["query", "collections", "topics", "username", "orientation"];
const TTL = 60;                                       // secondi — protegge la quota oraria

const host = (value) => { try { return new URL(value).hostname; } catch { return null; } };

export default {
  async fetch(req, env, ctx) {
    // 0. Solo GET: la Cache API rifiuta di memorizzare qualsiasi altro metodo, e un
    //    endpoint di immagini non ha altro verbo a cui rispondere.
    if (req.method !== "GET")
      return new Response("Method not allowed", { status: 405 });
    const url = new URL(req.url);

    // 1. Solo le tue pagine possono incorporarlo — un endpoint pubblico di foto
    //    casuali sulla rete aperta è un rate limit altrui da bruciare.
    const ref = req.headers.get("referer");       // assente su molti client legittimi
    if (ref && !ALLOWED.includes(host(ref)))
      return new Response("Forbidden", { status: 403 });

    // 2. Cache per combinazione di parametri, così una pagina con 12 immagini
    //    costa una chiamata API al minuto invece di dodici per render.
    const cache = caches.default;
    const hit = await cache.match(req);
    if (hit) return hit;

    // 3. Chiedi all'API ufficiale una foto casuale.
    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",
    }});
    // Un 403 qui di solito significa la quota oraria, non una chiave errata — alza il TTL, non allarmarti.
    if (!r.ok) return new Response("Upstream " + r.status, { status: 502 });
    const photo = await r.json();

    // 4. Ricostruisci l'URL dell'immagine: mantieni ixid, aggiungi i parametri di dimensionamento del chiamante.
    const img = new URL(photo.urls.raw);          // .raw porta già 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,
      // Il credito viaggia col redirect; i valori degli header devono essere ASCII, da qui la codifica.
      "X-Photo-Credit": encodeURIComponent(photo.user.name + " on Unsplash"),
      "X-Photo-Link": photo.links.html,
    }});
    ctx.waitUntil(cache.put(req, res.clone()));
    return res;
  },
};

Migrare un URL diventa quindi una ricerca e sostituzione, il che è esattamente ciò che rende questa opzione degna dei venti minuti richiesti:

sostituzione uno a uno
- https://source.unsplash.com/collection/67920491/1600x900
+ https://img.example.com/?collections=67920491&w=1600&h=900&fit=crop

Due note di design, entrambe costate a qualcuno un brutto pomeriggio prima di essere messe per iscritto. Il redirect (302) invece del proxy dei byte ti tiene fuori dal problema della banda e mantiene la visualizzazione conteggiata sulla CDN di Unsplash, che è ciò che chiedono le linee guida. E il controllo del Referer è deliberatamente permissivo quando l'header è assente — molti client legittimi lo rimuovono — pur bloccando comunque il caso ovvio in cui il tuo endpoint diventa la API di immagini gratuita di qualcun altro.

Le regole che eredita nel momento in cui usi l'API

Source non aveva regole perché non aveva account. L'API ne ha cinque che cambiano il modo in cui architetti la cosa, tutte dall'attuale documentazione:

  • I rate limit sono orari, e piccoli all'inizio. 50 richieste/ora in modalità demo; 1.000/ora dopo che la tua applicazione è stata approvata per la produzione. Contano solo le chiamate a api.unsplash.com — le richieste di immagini a images.unsplash.com non contano. Leggi X-Ratelimit-Remaining su ogni risposta.
  • L'hotlinking è obbligatorio, non semplicemente consentito. Unsplash richiede che gli URL delle immagini restituiti dall'API siano incorporati direttamente, così le visualizzazioni delle foto possono essere attribuite al fotografo. Mirroring del file sulla propria CDN è l'unica ottimizzazione che non sei libero di fare.
  • Mantieni il parametro ixid. Ridimensionare e ritagliare l'URL restituito è previsto; rimuovere il parametro che identifica la tua applicazione no.
  • Attribuzione e tracciamento dei download fanno parte dell'accordo — il fotografo e Unsplash ricevono il credito, e un “download” viene segnalato attraverso l'endpoint di download della foto quando un utente preleva il file, il che è un evento che devi far scattare tu stesso.
  • I prodotti distribuiti necessitano di registrazione dinamica del client. Se distribuisci un plugin, un tema o un CMS self-hosted, una chiave condivisa è sia una violazione della policy sia un singolo punto di guasto; l'API ha un flusso di registrazione proprio per quel caso.

Questo è il momento di essere onesti sull'ambito: se stai comunque collegando un'API e una chiave, la scelta di quale API di immagini improvvisamente si riapre, ed vale la pena dedicarci cinque minuti prima di scrivere il client. Abbiamo confrontato quelle gratuite — quote, regole, comportamento di ricerca e forme delle risposte — in il confronto tra API gratuite di foto stock.

Se volevi solo un segnaposto, dillo

Una grande quota dell'uso di Source non aveva mai a che fare con Unsplash. Era “metti qualcosa a forma di immagine qui mentre costruisco il layout”. Per questo, esistono ancora servizi senza chiave e sono la risposta corretta:

ServizioChiave?Cosa ottieniDove si ferma
Lorem Picsum No Fotografie reali: picsum.photos/800/600, una stabile con /id/237/… o /seed/xxx/…, più ?grayscale e ?blur=1..10. Il suo endpoint /v2/list attribuisce ogni foto alla sua pagina Unsplash e all'autore. Nessuna scelta del soggetto. La foto non avrà alcuna relazione con la tua pagina.
placehold.co No Rettangoli etichettati in qualsiasi dimensione — un riempimento onesto per wireframe. È un riquadro grigio, e sembra tale in uno screenshot condiviso con un cliente.
Openverse No Un catalogo con licenza aperta e API pubblica, gestito da WordPress.org. Corrispondenza per parole chiave, e le licenze variano per ogni elemento — devi leggerle.

La distinzione che conta: un segnaposto è per definizione temporaneo. Se l'immagine sopravvive fino alla produzione, non è più un segnaposto — è un'illustrazione che nessuno ha scelto, e il lettore se ne accorge.

Una chiave invece di tre

Ecco la parte della migrazione che nessuno pianifica: chi lascia Source raramente approda su un'unica API. Una pagina richiede un hero, due immagini di sezione e qualcosa per una griglia di card, e la risposta onesta di solito è Unsplash più Pexels più Pixabay — tre registrazioni, tre schemi di autenticazione, tre forme JSON, tre modelli di paginazione e tre insiemi di regole di attribuzione, tutto per riempire gli stessi tag <img>. Quel lavoro di integrazione è il conto reale per la scomparsa di un URL senza chiave, e arriva settimane dopo il disservizio che lo ha causato.

Racchiudere tutto ciò in un'unica integrazione è per cosa abbiamo costruito Pexafy: una singola chiave su 9 librerie a licenza gratuita in un unico schema, con ricerca semantica a livello di frase — così una descrizione completa come “a cracked phone screen on a wooden desk, shot from above” restituisce risultati classificati invece di nulla. Due limiti, dichiarati con chiarezza, perché questo intero articolo riguarda il non essere sorpresi due volte: richiede una chiave, quindi non ripristina ciò che Source era — appartiene alla stessa categoria dell'API Unsplash ufficiale menzionata sopra; e porta fotografia a licenza gratuita, non immagini editoriali o di marca.

Il pezzo genuinamente nuovo è rivolto agli assistenti citati sopra: un server MCP su mcp.pexafy.com/mcp significa che un modello che altrimenti reciterebbe un URL di immagine a memoria può cercare in un catalogo reale e restituire una foto che esiste, con la sua riga di credito allegata. È una risposta migliore agli URL morti scritti dalle macchine di qualsiasi regola di lint, e il ragionamento è esposto in image search infrastructure for AI agents.

Verifica il tuo patrimonio in dieci minuti

Qualunque cosa tu migri, fai prima questa parte — non puoi correggere URL che non hai trovato. Source è solo l'esempio di oggi; gli stessi tre passaggi si applicano a ogni risorsa esterna che incorpori.

trova ogni riferimento morto, poi tienili fuori
# 1. Tutto nel repo, inclusi documenti, test, fixture e README.
grep -rn --binary-files=without-match \
  -e "source.unsplash.com" -e "via.placeholder.com" -e "/placeholder.png" .

# 2. Tutto ciò che il database contiene — i corpi dei CMS sono dove queste cose si nascondono più a lungo.
psql -c "SELECT id FROM posts WHERE body LIKE '%source.unsplash.com%'"

# 3. Tutto ciò che il sito compilato richiede realmente: fai il crawling e elenca i fallimenti.
#    Confronta l'attributo, non un'estensione di file — gli URL di immagini raramente finiscono in .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   ← ciò che stai cercando

Poi decidi, una volta per tutte, quanto le immagini esterne possano costarti. Quattro regole che sopravvivono alla prossima chiusura, chiunque la causi:

  1. Recupera al momento della build, non al momento della richiesta. Un'immagine risolta durante la build fallisce in CI, davanti a uno sviluppatore, invece che alle 3 del mattino davanti a un utente.
  2. Non lasciare mai che una risorsa decorativa blocchi un percorso critico. Non precaricare nulla esterno sopra un form di login; dai a ogni <img> di terze parti un fallback onerror e width/height espliciti così che un fallimento costi un riquadro vuoto, non uno spostamento di layout o uno script bloccato.
  3. Aggiungi il controllo alla CI. Il passaggio 3 sopra, eseguito sul tuo output compilato, trasforma “qualcuno alla fine se n'è accorto” in una build rossa. È l'unico passaggio che previene le recidive.
  4. Metti a budget le tue dipendenze esterne come qualsiasi altra. Scrivi da quali host le tue pagine possono dipendere e cosa succede quando ciascuno è offline. Un URL per cui non hai dovuto registrarti è comunque una dipendenza — Source ha dimostrato che è semplicemente una di cui nessuno è responsabile.

Riferimenti e note

1 Ogni codice di stato, conteggio e riga citata in questo articolo è stato prelevato dalla sua fonte primaria il 30 agosto 2026. I codici di stato HTTP sono stati rilevati con curl su ogni pattern di URL; tutti hanno restituito 503 con server: Heroku e un corpo che incorpora herokucdn.com/error-pages/application-error.html. La risoluzione DNS è stata confermata lo stesso giorno (un CNAME verso un host herokudns.com).

2 Entrambe le voci di changelog sono citate testualmente da unsplash.com/documentation/changelog. Il testo della politica di deprecazione (3 settimane di preavviso, header Warning, e l'esenzione per gli endpoint non pubblicamente documentati) proviene da unsplash.com/documentation, stesso giorno.

3 Il fallimento TLS è stato riprodotto con openssl s_client -connect changelog.unsplash.com:443 (tlsv1 alert internal error). La catena di redirect è stata seguita con curl -L. Il divario dell'archivio è stato rilevato dall' API CDX di Wayback: ultima cattura 200 di changelog.unsplash.com il 20240324, prima di unsplash.com/documentation/changelog il 20240823.

4 Titoli, date di creazione e chiusura delle issue letti dall'API REST di GitHub (mui/material-ui#42736, nextcloud/unsplash#115, sindresorhus/Actions#248) e dall'API JSON di drupal.org per la issue 3324054 di gin_login, il cui corpo riporta “I get always a Heroku application error” nel novembre 2022.

5 Conteggi: API di ricerca codice GitHub (3.344 file; un campione di 100 risultati deduplicato a 77 repository, di cui 12 creati dopo l'11 giugno 2024 e 20 con push nei 12 mesi precedenti); API dei download del registro npm (unsplash-source-es6, 23 download nei 30 giorni precedenti); /search/excerpts di Stack Exchange (1.459 post). La ricerca codice copre solo repository pubblici indicizzati, quindi ogni cifra è un minimo.

Domande frequenti

source.unsplash.com è down, oppure è stato disattivato definitivamente?
Definitivamente. Unsplash ha annunciato la dismissione l'11 giugno 2024 — “inizieremo a ridurre il servizio disabilitando prima la funzione di ricerca, e nelle settimane successive disattiveremo completamente l'applicazione” — dopo averlo deprecato il 25 novembre 2021. Ogni pattern (/random, /1600x900/?query, /collection/…, /daily) restituisce HTTP 503 con la generica pagina di Application Error di Heroku. Il nome host risolve ancora, quindi il guasto si manifesta come un'immagine rotta piuttosto che come un errore di rete.
Qual è il sostituto diretto di source.unsplash.com/random?
Non esiste un'alternativa senza chiave pronta all'uso, ed è meglio accettarlo fin da subito. Esistono tre sostituti. Un URL CDN fisso — images.unsplash.com/photo-…?w=1600&h=900&fit=crop — non richiede alcuna chiave ma restituisce sempre la stessa foto, il che è in realtà ciò di cui necessitavano molti usi decorativi. L'API ufficiale, GET https://api.unsplash.com/photos/random con un header Authorization: Client-ID, ripristina la casualità ma deve essere chiamata lato server. Un piccolo proxy di tua proprietà davanti a quell'endpoint è l'unica opzione che restituisce un URL senza chiave inseribile direttamente in un tag <img>.
Perché gli strumenti di coding AI generano ancora URL source.unsplash.com nel 2026?
Perché l'URL è stato documentato, insegnato e copiato per circa otto anni, e un corpus di addestramento non scade quando lo fa un servizio. Misurato il 30 agosto 2026: la ricerca del codice su GitHub restituisce ancora 3.344 file che lo contengono, e in un campione di 100 file 12 dei 77 repository sono stati creati dopo lo spegnimento. Anche le librerie di prompt scritte da esseri umani ripetono l'istruzione — un prompt GPT ampiamente copiato dice ancora al modello di “usare l'API di unsplash( https://source.unsplash.com/1280x720/?… )”. Considera qualsiasi URL di immagine scritto da un modello come non verificato e controlla i codici di stato in CI.
Posso ancora ottenere una foto casuale di Unsplash senza una chiave API?
Non direttamente da Unsplash — la selezione casuale ora vive dietro /photos/random, che richiede un Client-ID. Le due strade senza chiave sono un proxy che ospiti tu stesso, dove la chiave resta lato server e l'URL pubblico assomiglia a quello vecchio, oppure un servizio di placeholder di terze parti come Lorem Picsum (picsum.photos/800/600), che serve fotografie reali senza chiave ma senza alcun controllo sul soggetto.
L'API Unsplash permette di scaricare e ospitare autonomamente le immagini?
No. A differenza della maggior parte delle API, Unsplash richiede l'hotlinking: gli URL delle immagini restituiti dall'API devono essere incorporati direttamente, in modo che le visualizzazioni della foto vengano conteggiate a favore del fotografo. Da questo derivano tre obblighi — mantenere il parametro ixid quando ridimensioni o ritagli l'URL, accreditare il fotografo e Unsplash, e attivare l'endpoint di download della foto quando un utente scarica il file. Replicare i file sulla tua CDN è l'unica ottimizzazione che non sei libero di fare.
Perché l'avviso di deprecazione del 2021 non ha protetto gli utenti esistenti?
Perché l'avviso e la policy non riguardavano la stessa cosa. La voce del changelog del 25 novembre 2021 prometteva che “gli usi esistenti continueranno a funzionare” e non indicava alcuna data di fine. La policy di deprecazione pubblicata da Unsplash — almeno tre settimane di preavviso più un header Warning — si applica ai campi ed endpoint pubblicamente documentati, e lo stesso paragrafo afferma che tutto ciò che non è documentato può cambiare senza preavviso. Source non è mai stato un endpoint documentato dell'API, quindi restava fuori dalla policy che avrebbe potuto proteggerlo.
Come trovo tutti gli URL source.unsplash.com morti nel mio progetto?
Tre passaggi, dieci minuti. Fai un grep del repository includendo documentazione, test, fixture e README — grep -rn "source.unsplash.com" . — poiché questi URL sopravvivono più a lungo nel codice di esempio. Interroga il database, perché è nel corpo degli articoli del CMS che si nascondono (WHERE body LIKE '%source.unsplash.com%'). Poi esegui la scansione del tuo output compilato: estrai ogni URL di immagine e richiedilo, elencando tutto ciò che non restituisce 200. Aggiungi quest'ultimo passaggio alla CI e un asset di terze parti morto farà fallire una build invece di una pagina.

Basta cercare parole chiave. Descrivi ciò che intendi.

Cerca 9M+ immagini libere per significato — in qualsiasi lingua, in meno di 100 ms.