From 42c216b00bbe504f8818af7d3c4ccee9d93398ab Mon Sep 17 00:00:00 2001 From: jubnl Date: Wed, 15 Apr 2026 22:02:48 +0200 Subject: [PATCH] fix(immich): serve fullsize thumbnail for original to fix HEIC rendering Raw /assets/{id}/original returns HEIC bytes which only Safari can render natively. Switch to /assets/{id}/thumbnail?size=fullsize which Immich transcodes to a browser-compatible format. Closes #668 --- server/src/services/memories/immichService.ts | 5 +++-- server/tests/integration/memories-immich.test.ts | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/server/src/services/memories/immichService.ts b/server/src/services/memories/immichService.ts index 77c8c26d..41c078fe 100644 --- a/server/src/services/memories/immichService.ts +++ b/server/src/services/memories/immichService.ts @@ -241,9 +241,10 @@ export async function streamImmichAsset( const creds = getImmichCredentials(effectiveUserId); if (!creds) return { error: 'Not found', status: 404 }; - const path = kind === 'thumbnail' ? 'thumbnail' : 'original'; const timeout = kind === 'thumbnail' ? 10000 : 30000; - const url = `${creds.immich_url}/api/assets/${assetId}/${path}`; + const url = kind === 'thumbnail' + ? `${creds.immich_url}/api/assets/${assetId}/thumbnail?size=thumbnail` + : `${creds.immich_url}/api/assets/${assetId}/thumbnail?size=fullsize`; response.set('Cache-Control', 'public, max-age=86400'); await pipeAsset(url, response, { 'x-api-key': creds.immich_api_key }, AbortSignal.timeout(timeout)); diff --git a/server/tests/integration/memories-immich.test.ts b/server/tests/integration/memories-immich.test.ts index 7cd07bab..eb19cd48 100644 --- a/server/tests/integration/memories-immich.test.ts +++ b/server/tests/integration/memories-immich.test.ts @@ -407,7 +407,7 @@ describe('Immich asset proxy', () => { .set('Cookie', authCookie(member.id)); expect(res.status).toBe(200); - expect(res.headers['content-type']).toContain('image/jpeg'); + expect(res.headers['content-type']).toContain('image/'); }); it('IMMICH-057 — GET /assets/info where trip does not exist returns 403', async () => {