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.
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:
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/random | Una foto casuale, di qualsiasi dimensione | 503 |
source.unsplash.com/random/1600x900 | Una foto casuale, ritagliata alla dimensione | 503 |
source.unsplash.com/1600x900/?apple,desk | Una foto casuale corrispondente ai termini di ricerca | 503 |
source.unsplash.com/featured/1600x900?nature | Una foto casuale in evidenza | 503 |
source.unsplash.com/collection/190727/800x600 | Una foto casuale da una collezione | 503 |
source.unsplash.com/user/scottwebb/1600x900 | Una foto casuale da un fotografo specifico | 503 |
source.unsplash.com/daily | La foto del giorno | 503 |
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:
- L'endpoint HTTPS è rotto.
openssl s_client -connect changelog.unsplash.com:443restituiscetlsv1 alert internal error— l'handshake fallisce prima che venga presentato qualsiasi certificato. Ogni link dell'epoca 2021, che era inhttps://, è quindi morto in un browser. - Su HTTP semplice reindirizza, ma non in modo utile. Seguendo
http://changelog.unsplash.com/deprecations/2021/11/25/source-deprecation.htmlsi finisce, due salti dopo, su un400suunsplash.com/@documentation/changelog/deprecations/2021/11/25/source-deprecation/html— il percorso è stato inghiottito dalla route dei nomi utente del sito. - 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:
| Misurazione | Valore al 30 ago 2026 | Come è 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:
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:
<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.
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.
// 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:
- 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 aimages.unsplash.comnon contano. LeggiX-Ratelimit-Remainingsu 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:
| Servizio | Chiave? | Cosa ottieni | Dove 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.
# 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:
- 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.
- 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 fallbackonerrorewidth/heightespliciti così che un fallimento costi un riquadro vuoto, non uno spostamento di layout o uno script bloccato. - 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.
- 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.
Fonti primarie: Changelog API Unsplash · Documentazione API Unsplash · Linea guida di attribuzione Unsplash · Stato Unsplash · MUI #42736 · Nextcloud #115 · sindresorhus/Actions #248 · Drupal Gin Login #3324054 · Lorem Picsum · Openverse · Documentazione API & MCP di Pexafy.
Domande frequenti
source.unsplash.com è down, oppure è stato disattivato definitivamente?
/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?
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?
Posso ancora ottenere una foto casuale di Unsplash senza una chiave API?
/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?
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?
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?
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.