Media
Obrazy i pliki żyją w bibliotece mediów workspace'u. Jak odwołują się do nich bloki, dlaczego każdy upload ma własny URL i co to znaczy przy podmianie.
Media są na poziomie workspace'u, nie strony. Jedna biblioteka, poukładana w foldery, współdzielona przez każdą stronę i każdy blok.
Pole media
Blok sięga po zasób przez fields.media:
export const imageProps = {
src: fields.media({ label: "Image", required: true }),
alt: fields.text({ label: "Alt text" }),
};Przechowywana wartość to string z URL-em, nie id i nie obiekt. Twój komponent dostaje go gotowego do użycia:
function ImageBlock({ content }) {
if (!content.src) return null;
return <img src={content.src} alt={content.alt ?? ""} />;
}Ponieważ wartością jest zwykły URL, pole media nic nie kosztuje przy renderze - nie ma wyszukiwania, nie ma kroku rozwiązywania i nie ma stanu, w którym obrazek się jeszcze ładuje.
Każdy upload dostaje własny URL
Wgrane zasoby są serwowane z hosta CDN, z hashem w ścieżce:
https://assets.cmssy.io/{workspaceId}/78aa0167-cmssy-og-default.pngTen hash jest per upload. To właśnie czyni zasoby niezmiennymi i bezpiecznie cache'owalnymi na zawsze - ale ma konsekwencję, którą ludzie poznają na twardo:
Wgranie zamiennika nie aktualizuje bloków wskazujących na stary plik. Nowy upload to nowy URL; istniejące bloki trzymają stary i dalej renderują stary obrazek. Jeśli podmieniłeś logo, a serwis dalej pokazuje poprzednie, nic nie jest źle zcache'owane - bloki po prostu wskazują tam, gdzie zawsze.
Nie ma podmiany w miejscu: narzędzia do mediów to listowanie, wgrywanie i przenoszenie, więc nowy plik zawsze oznacza nowy URL. Lekarstwem jest przepięcie bloków - search-and-replace po treści bloków, w czym serwer MCP jest akurat dobry.
Praktyczną konsekwencję warto zaplanować z góry. Zasób, do którego odwołuje się wiele stron - logo, domyślny obrazek OG - taniej podmienić, jeśli przechodzi przez konfigurację serwisu albo jeden blok, niż gdy jest wklejony w dwudziestu miejscach.
Foldery
Foldery to płaskawe drzewo z parentId. Porządkują bibliotekę dla ludzi; nie są częścią URL-a, więc przeniesienie zasobu między folderami niczego nie psuje.
Przez MCP możesz listować, tworzyć, zmieniać nazwy, usuwać i przenosić - co zamienia hurtową reorganizację w skrypt zamiast popołudnia przeciągania myszą.
Obrazy w Next.js
Zasoby przychodzą z innego originu niż Twoja aplikacja, więc next/image będzie je odrzucać, dopóki host nie zostanie dopuszczony:
// next.config.mjs
const nextConfig = {
images: {
remotePatterns: [
{ protocol: "https", hostname: "assets.cmssy.io" },
],
},
};Wildcard hostname: "**" działa i tego używa aplikacja referencyjna, ale przepuszcza dowolny host HTTPS przez Twój optymalizator obrazów. Nazwanie hosta zasobów jest cięższym wyborem i kosztuje jedną linię.
Alt to treść
Do każdego fields.media dodaj pole tekstowe na alt i pozwól redaktorom je wypełnić. Alt opisuje, co obrazek znaczy w tym kontekście - to samo zdjęcie potrzebuje innego altu w case study i w ścianie logotypów. Nie może być właściwością pliku, dlatego należy do bloku, a nie do biblioteki.
Następne kroki
- Schemat bloku i typy pól -
fields.mediapośród reszty. - Serwer MCP - skryptowanie uploadów i przenoszenia.
- Branding - logo i obrazek OG w konfiguracji serwisu.