관리자는 플러그인 레지스트리에서 샌드박스된 플러그인을 설치하거나 astro.config.mjs에 npm 패키지를 등록할 수 있습니다. 구성 기반 플러그인은 샌드박스에서 실행할 수도 있고 사이트 프로세스에서 실행할 수도 있습니다.
관리자 설치 준비
레지스트리 설치에는 다음이 필요합니다.
plugins:manage권한이 있는 관리자 계정.- 다운로드한 플러그인 번들을 위한 구성된 스토리지.
- 사용 가능한 샌드박스 러너.
Cloudflare Workers에서는 @emdash-cms/cloudflare의 sandbox()를 사용하세요.
import { sandbox } from "@emdash-cms/cloudflare";
import { defineConfig } from "astro/config";
import emdash from "emdash/astro";
export default defineConfig({
integrations: [
emdash({
sandboxRunner: sandbox(),
}),
],
});
Cloudflare 러너는 Worker Loader를 사용해 플러그인마다 별도의 Worker를 만듭니다. Workers Paid 플랜과 LOADER라는 이름의 worker_loaders 바인딩이 필요합니다. 샌드박스된 플러그인은 PluginBridge를 통해 콘텐츠, 미디어, 스토리지, 네트워크, 이메일 API에 접근하므로, 사이트의 Worker 진입점이 해당 클래스를 내보내야 합니다.
*-cloudflare 템플릿은 PluginBridge를 내보내지만 Worker Loader 바인딩은 주석 처리된 상태로 두므로, 새 프로젝트를 Workers 무료 플랜에 배포할 수 있습니다. 프로젝트를 생성하는 동안 샌드박스된 플러그인을 활성화하거나, Cloudflare 샌드박스 설정을 따라 나중에 바인딩을 추가하세요. sandbox() 헬퍼는 빌드 시점에 실제로 적용되는 Wrangler 구성을 읽습니다. LOADER가 없으면 레지스트리 둘러보기는 계속 사용할 수 있지만, 구성으로 관리되는 샌드박스된 플러그인은 로드되지 않으며 설치 또는 업데이트 요청은 SANDBOX_NOT_AVAILABLE을 반환합니다.
Node.js에서는 러너와 그 피어 의존성인 workerd를 설치하세요.
npm install @emdash-cms/sandbox-workerd workerd
workerd 프로세스는 플러그인 코드를 Node.js 서버와 분리해서 실행합니다. EmDash 통합에서 러너를 선택하세요.
import { defineConfig } from "astro/config";
import emdash from "emdash/astro";
export default defineConfig({
integrations: [
emdash({
sandboxRunner: "@emdash-cms/sandbox-workerd/sandbox",
}),
],
});
개발 설정, 런타임 요구 사항, 리소스 제한, 두 플랫폼에서 러너를 사용할 수 없을 때의 오류는 플러그인 샌드박스 구성을 참고하세요.
레지스트리에서 설치
- 관리자 패널에서 Registry를 엽니다.
- 플러그인을 검색하고 상세 페이지를 엽니다.
- 릴리스를 선택하고 게시자, 메타데이터, 요청된 권한, 검증 상태를 검토합니다.
- Install을 선택합니다.
- 동의 대화 상자에서 검증된 릴리스 식별자와 권한을 검토한 뒤 확인합니다.
EmDash는 게시자의 현재 서명된 레코드를 검증하고, 다운로드한 번들을 샌드박스 러너로 로드하기 전에 검사합니다. 플러그인은 Plugins 아래에 나타나며, 거기서 비활성화하거나 구성할 수 있습니다. 전체 검증 및 신뢰 모델은 플러그인 레지스트리를 참고하세요.
권한 검토
동의 대화 상자에는 플러그인이 선언한 모든 권한이 표시됩니다. 일반적인 권한은 다음과 같습니다.
| 권한 | 부여되는 접근 |
|---|---|
content:read | 사이트 콘텐츠 읽기 |
content:write | 콘텐츠 생성, 업데이트, 삭제 |
content:revisions:read | 보존된 콘텐츠 리비전 기록 읽기 |
schema:read | 컬렉션과 필드 정의 읽기 |
bylines:read | 공개 바이라인 프로필과 콘텐츠 크레딧 읽기 |
redirects:read | 리디렉션 규칙 읽기 |
redirects:write | 방문자가 이동하는 위치 변경 |
media:read | 준비된 미디어의 안전한 메타데이터 읽기 |
media:bytes:read | 준비된 미디어의 파일 내용과 콘텐츠 해시 읽기 |
media:metadata:write | 미디어의 대체 텍스트, 캡션, 초점 변경 |
media:write | 미디어 업로드, 교체, 삭제 |
network:request | 플러그인에 허용된 호스트 목록으로 요청 전송 |
플러그인이 Model Context Protocol(MCP) 도구로 노출되는 플러그인 라우트를 선언한 경우, 대화 상자에는 그 라우트도 표시됩니다. 전체 권한 모델은 Capability와 보안을 참고하세요.
플러그인 업데이트
- 관리자 패널에서 Plugins를 엽니다.
- Check for updates를 선택합니다.
- 사용 가능한 릴리스가 있는 레지스트리 플러그인에서 Update를 선택합니다.
- 동의 대화 상자를 검토한 뒤 업데이트를 확인합니다.
레지스트리 업데이트가 권한이나 MCP 도구를 추가하거나, 라우트를 인증 필요에서 공개로 바꾸는 경우에는 한 번 더 확인해야 합니다. 변경을 승인하기 전까지 EmDash는 설치된 버전을 그대로 둡니다.
명시적인 업데이트는 앞으로만 진행됩니다. 레지스트리의 최신 릴리스를 따라가는 업데이트는 게시자가 최신 릴리스를 철회하면 롤백될 수 있습니다. 그 밖의 경우에 이전 릴리스로 돌아가려면 플러그인을 제거한 다음 레지스트리 페이지에서 해당 버전을 설치하세요. 삭제를 선택하지 않는 한 제거해도 플러그인의 저장된 데이터는 유지됩니다.
플러그인 제거
- 관리자 패널에서 Plugins를 열고 설치된 플러그인을 펼칩니다.
- Uninstall을 선택합니다.
- 나중에 다시 설치할 때 플러그인의 저장된 데이터가 필요하지 않은 경우에만 Also delete plugin storage data를 선택합니다.
- 제거를 확인합니다.
EmDash는 설치된 번들을 제거하고 플러그인 로드를 중단합니다. 플러그인 스토리지 데이터는 기본적으로 남아 있습니다.
npm에서 설치
네이티브 플러그인과 구성으로 관리되는 샌드박스된 플러그인은 npm 의존성으로 설치됩니다. 패키지의 안내에 따라 plugins: [] 또는 sandboxed: [] 중 하나를 선택하세요.
다음 예시는 네이티브 Field Kit 플러그인을 등록합니다.
import { defineConfig } from "astro/config";
import emdash from "emdash/astro";
import { fieldKitPlugin } from "@emdash-cms/plugin-field-kit";
export default defineConfig({
integrations: [
emdash({
plugins: [fieldKitPlugin()],
}),
],
});
구성으로 관리되는 플러그인은 npm 의존성을 업데이트하고 사이트를 배포할 때 바뀝니다. 관리자 패널에서 설치하거나 제거할 수 없습니다.
설치 방법 선택
| 레지스트리 | sandboxed: []를 사용하는 npm | plugins: []를 사용하는 npm | |
|---|---|---|---|
| 설치 및 업데이트 | 관리자 패널 | 의존성 변경 및 배포 | 의존성 변경 및 배포 |
| 실행 위치 | 구성된 샌드박스 러너 | 구성된 샌드박스 러너 | 사이트 프로세스 |
| EmDash 접근 | 선언된 플러그인 API만 | 선언된 플러그인 API만 | 선언된 플러그인 API와 프로세스 직접 접근 |
Node.js API 및 직접 fetch() | 사용 불가 | 사용 불가 | 사용 가능 |
| React 관리자 컴포넌트 | 사용 불가 | 사용 불가 | 사용 가능 |
| Portable Text 렌더러 | 사용 불가 | 사용 불가 | 사용 가능 |
플러그인에 React 관리자 컴포넌트, Portable Text 렌더러, 페이지 프래그먼트가 필요하거나 사이트 프로세스에 직접 접근해야 한다면 네이티브 플러그인을 사용하세요. 선언된 플러그인 API를 통해 동작할 수 있다면 샌드박스된 플러그인을 사용하세요.