EmDash에는 이미지, 문서 및 기타 파일을 관리하기 위한 미디어 라이브러리가 포함되어 있습니다. 이 가이드는 콘텐츠에서 미디어를 업로드, 정리 및 사용하는 방법을 다룹니다.
미디어 라이브러리 접근
관리자 사이드바에서 Media를 클릭하여 미디어 라이브러리를 엽니다. 라이브러리는 업로드된 모든 파일을 미리보기, 파일명 및 업로드 날짜와 함께 표시합니다.
파일 업로드
미디어 라이브러리에서
-
관리자 사이드바에서 Media 클릭
-
Upload를 클릭하거나 업로드 영역에 파일을 드래그
-
컴퓨터에서 하나 이상의 파일 선택
-
업로드 완료 대기
콘텐츠 편집기에서
-
리치 텍스트 편집기에서 이미지 버튼 클릭
-
미디어 선택기에서 Upload 클릭
-
컴퓨터에서 파일 선택
-
대체 텍스트를 추가하고 삽입 클릭
지원되는 파일 유형
EmDash는 일반적인 웹 파일 유형을 지원합니다:
| 카테고리 | 확장자 |
|---|---|
| 이미지 | .jpg, .jpeg, .png, .gif, .webp, .avif, .svg |
| 문서 | .pdf, .doc, .docx, .xls, .xlsx, .ppt, .pptx |
| 동영상 | .mp4, .webm, .mov |
| 오디오 | .mp3, .wav, .ogg |
스토리지 백엔드
EmDash는 여러 스토리지 백엔드를 지원합니다. Astro 설정에서 스토리지를 구성합니다:
로컬 스토리지
import { defineConfig } from "astro/config";
import emdash, { local } from "emdash/astro";
export default defineConfig({
integrations: [
emdash({
storage: local({
directory: "./uploads",
baseUrl: "/_emdash/api/media/file",
}),
}),
],
});파일은 ./uploads 디렉토리에 저장됩니다. 개발 및 단일 서버 배포에 적합합니다.
Cloudflare R2
import { defineConfig } from "astro/config";
import emdash from "emdash/astro";
import { r2 } from "@emdash-cms/cloudflare";
export default defineConfig({
integrations: [
emdash({
storage: r2({
binding: "MEDIA_BUCKET",
publicUrl: "https://media.example.com",
}),
}),
],
});wrangler.jsonc에 구성된 R2 버킷이 필요합니다:
{
"r2_buckets": [
{
"binding": "MEDIA_BUCKET",
"bucket_name": "my-media-bucket",
},
],
} S3 호환
import { defineConfig } from "astro/config";
import emdash, { s3 } from "emdash/astro";
export default defineConfig({
integrations: [
emdash({
storage: s3({
endpoint: "https://s3.amazonaws.com",
bucket: "my-media-bucket",
accessKeyId: process.env.S3_ACCESS_KEY_ID,
secretAccessKey: process.env.S3_SECRET_ACCESS_KEY,
region: "us-east-1",
publicUrl: "https://media.example.com",
}),
}),
],
});Cloudflare R2(S3 API 경유), MinIO 및 기타 S3 호환 서비스에서 작동합니다.
업로드 작동 방식
EmDash는 안전한 업로드를 위해 서명된 URL을 사용합니다:
-
클라이언트가 API에서 업로드 URL을 요청
-
서버가 만료 시간이 있는 서명된 URL을 생성
-
클라이언트가 서명된 URL을 사용하여 스토리지에 직접 업로드
-
서버가 파일 메타데이터를 데이터베이스에 기록
이 접근 방식은 대용량 파일을 애플리케이션 서버에서 분리하고 클라우드 스토리지로의 직접 업로드를 가능하게 합니다.
미디어 정리
폴더
폴더를 만들어 미디어를 정리합니다:
-
미디어 라이브러리에서 New Folder 클릭
-
폴더 이름 입력
-
만들기 클릭
-
파일을 폴더로 드래그하여 정리
검색
검색 상자를 사용하여 이름으로 파일을 찾습니다. 검색은 부분 파일명도 일치합니다.
필터
미디어 필터링:
- 유형 - 이미지, 문서, 동영상, 오디오
- 날짜 - 업로드 날짜 범위
- 폴더 - 특정 폴더
콘텐츠에서 미디어 사용
리치 텍스트 편집기에서
-
이미지를 배치할 위치에 커서를 놓기
-
도구 모음의 이미지 버튼 클릭
-
미디어 라이브러리에서 이미지를 선택하거나 새 이미지를 업로드
-
대체 텍스트 입력
-
삽입 클릭
대표 이미지로
-
편집기에서 콘텐츠 항목 열기
-
사이드바에서 Featured Image 필드 찾기
-
이미지 선택 클릭
-
미디어 라이브러리에서 선택 또는 업로드
-
저장 클릭
사용자 정의 필드에서
이미지 또는 파일 유형으로 구성된 필드의 경우, 필드를 클릭하여 미디어 선택기를 엽니다.
템플릿에서 미디어 표시
콘텐츠 데이터에서 미디어 URL에 접근합니다:
---
import { getEmDashEntry } from "emdash";
const { entry: post } = await getEmDashEntry("posts", Astro.params.slug);
---
{post?.data.featured_image && (
<img
src={post.data.featured_image}
alt={post.data.featured_image_alt ?? ""}
/>
)}
반응형 이미지
EmDash 미디어 필드에는 emdash/ui의 Image 컴포넌트를 사용합니다:
---
import { Image } from "emdash/ui";
import { getEmDashEntry } from "emdash";
const { entry: post } = await getEmDashEntry("posts", Astro.params.slug);
---
{post?.data.featured_image && (
<Image
image={post.data.featured_image}
width={800}
height={450}
priority
/>
)}
priority는 첫 화면의 주요 이미지용입니다. loading="eager"와 fetchpriority="high"를 설정합니다. loading은 로딩을 지연시킬지 여부를 제어하고, fetchpriority는 브라우저에 요청의 우선순위 힌트를 제공합니다.
미디어 삭제
-
삭제할 파일 선택
-
삭제 클릭
-
삭제 확인
미디어 API
관리자 API를 사용하여 프로그래밍 방식으로 미디어에 접근합니다.
파일 업로드
멀티파트 폼 데이터로 미디어를 업로드합니다:
POST /_emdash/api/media
Content-Type: multipart/form-data
Authorization: Bearer YOUR_API_TOKEN
file=<binary file data>
성공적인 업로드는 저장된 미디어 항목을 반환합니다:
{
"success": true,
"data": {
"item": {
"id": "01ABC123",
"filename": "hero-image.jpg",
"mime_type": "image/jpeg",
"storage_key": "media/abc123/hero-image.jpg",
"width": 1200,
"height": 800
}
}
}
미디어 목록 조회
다음 요청은 접두사 아래의 미디어를 나열합니다:
GET /_emdash/api/media?prefix=images/&limit=20
Authorization: Bearer YOUR_API_TOKEN
미디어 삭제
다음 요청은 저장된 파일을 삭제합니다:
DELETE /_emdash/api/media/images/hero.jpg
Authorization: Bearer YOUR_API_TOKEN
미디어 프로바이더
로컬 스토리지 외에도 EmDash는 전문적인 이미지 및 동영상 호스팅을 위한 외부 미디어 프로바이더를 지원합니다. 미디어 프로바이더는 미디어 선택기에서 탭으로 나타나며, 편집자가 여러 소스에서 선택할 수 있습니다.
사용 가능한 프로바이더
Cloudflare Images
Cloudflare Images는 자동 최적화, 리사이징, 포맷 변환이 포함된 이미지 호스팅을 제공합니다.
import { defineConfig } from "astro/config";
import emdash from "emdash/astro";
import { cloudflareImages } from "@emdash-cms/cloudflare";
export default defineConfig({
integrations: [
emdash({
// ... 데이터베이스, 스토리지 구성
mediaProviders: [
cloudflareImages({
accountId: import.meta.env.CF_ACCOUNT_ID,
apiToken: import.meta.env.CF_IMAGES_TOKEN,
// 선택사항: 사용자 정의 전달 도메인
deliveryDomain: "images.example.com",
}),
],
}),
],
});기능:
- 관리자에서 직접 이미지 탐색 및 업로드
- 자동 이미지 최적화 및 포맷 변환
- URL 기반 변환 (리사이즈, 크롭, 포맷)
- 반응형 이미지를 위한 유연한 배리언트
Cloudflare Stream
Cloudflare Stream은 HLS/DASH 적응형 스트리밍이 포함된 동영상 호스팅을 제공합니다.
import { defineConfig } from "astro/config";
import emdash from "emdash/astro";
import { cloudflareStream } from "@emdash-cms/cloudflare";
export default defineConfig({
integrations: [
emdash({
// ... 데이터베이스, 스토리지 구성
mediaProviders: [
cloudflareStream({
accountId: import.meta.env.CF_ACCOUNT_ID,
apiToken: import.meta.env.CF_STREAM_TOKEN,
// 선택사항: 플레이어 설정
controls: true,
autoplay: false,
loop: false,
}),
],
}),
],
});기능:
- 관리자에서 동영상 탐색, 검색, 업로드
- HLS 및 DASH 적응형 스트리밍
- 자동 썸네일 생성
- 대용량 파일 직접 업로드
여러 프로바이더 사용
여러 프로바이더를 구성할 수 있습니다. 각 프로바이더는 미디어 선택기에서 탭으로 나타납니다:
import { defineConfig } from "astro/config";
import emdash from "emdash/astro";
import { cloudflareImages, cloudflareStream } from "@emdash-cms/cloudflare";
export default defineConfig({
integrations: [
emdash({
database: d1({ binding: "DB" }),
storage: r2({ binding: "MEDIA" }),
mediaProviders: [
cloudflareImages({
accountId: import.meta.env.CF_ACCOUNT_ID,
apiToken: import.meta.env.CF_IMAGES_TOKEN,
}),
cloudflareStream({
accountId: import.meta.env.CF_ACCOUNT_ID,
apiToken: import.meta.env.CF_STREAM_TOKEN,
}),
],
}),
],
});
로컬 미디어 라이브러리(“Library” 탭)는 구성된 모든 프로바이더와 함께 항상 사용 가능합니다.
프로바이더 미디어 렌더링
Image 컴포넌트를 사용하여 미디어를 렌더링합니다:
---
import { Image } from "emdash/ui";
import { getEmDashEntry } from "emdash";
const { entry: post } = await getEmDashEntry("posts", Astro.params.slug);
---
{post?.data.featured_image && (
<Image
image={post.data.featured_image}
width={800}
height={450}
/>
)}
컴포넌트가 자동으로:
- 저장된 값에서 프로바이더를 감지
- 최적화된
<img>요소를 렌더링 - 프로바이더별 최적화를 적용 (예: Cloudflare Images 변환)
MediaValue 타입
미디어 필드는 프로바이더 정보를 포함하는 MediaValue 객체를 저장합니다:
interface MediaValue {
provider?: string; // 프로바이더 ID, 기본값 "local"
id: string; // 프로바이더별 ID
src?: string; // 직접 URL (로컬 미디어 또는 일반 문자열 값용)
previewUrl?: string; // 관리자 표시용 미리보기 URL (외부 프로바이더)
filename?: string; // 원본 파일명
mimeType?: string; // MIME 타입
width?: number; // 이미지/동영상 너비
height?: number; // 이미지/동영상 높이
alt?: string; // 대체 텍스트
meta?: Record<string, unknown>; // 프로바이더별 메타데이터
}
이를 통해 EmDash는 호스팅 위치에 관계없이 미디어를 올바르게 렌더링할 수 있습니다.