Teraz z AI - twórz strony przez serwer MCP

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.png

Ten 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