Skip to content

Latest commit

 

History

History
283 lines (222 loc) · 12.5 KB

rss.mdx

File metadata and controls

283 lines (222 loc) · 12.5 KB
title description i18nReady type
RSS 피드 추가하기
사용자가 콘텐츠를 구독할 수 있도록 Astro 사이트에 RSS 피드를 추가하기.
true
recipe

import Since from '/components/Since.astro'; import { Steps } from '@astrojs/starlight/components'; import PackageManagerTabs from '/components/tabs/PackageManagerTabs.astro';

Astro는 블로그 및 기타 콘텐츠 웹사이트를 위한 빠른 자동 RSS 피드 생성을 지원합니다. RSS 피드는 사용자가 콘텐츠를 쉽게 구독할 수 있는 방법을 제공합니다.

Setting up @astrojs/rss

패키지 @astrojs/rssAPI endpoints를 사용하여 RSS 피드를 생성하기 위한 헬퍼를 제공합니다. 이렇게 하면 SSR adapter를 사용할 때 정적 빌드 및 온디맨드 생성을 모두 사용할 수 있습니다.

1. 선호하는 패키지 관리자를 사용하여 `@astrojs/rss`를 설치하세요.
<PackageManagerTabs>
  <Fragment slot="npm">
  ```shell
  npm install @astrojs/rss
  ```
  </Fragment>
  <Fragment slot="pnpm">
  ```shell
  pnpm add @astrojs/rss
  ```
  </Fragment>
  <Fragment slot="yarn">
  ```shell
  yarn add @astrojs/rss
  ```
  </Fragment>
</PackageManagerTabs>

:::tip
프로젝트의 `astro.config`에 `site`(/ko/reference/configuration-reference/#site)를 설정했는지 확인합니다. 이 설정은 RSS 글에 대한 링크를 생성하는 데 사용됩니다.
:::
  1. src/pages/에 원하는 이름과 확장자 .xml.js를 사용하여 피드의 출력 URL로 사용할 파일을 만듭니다. 일반적인 RSS 피드의 URL 이름은 feed.xml 또는 rss.xml입니다.

    아래 예제 파일 src/pages/rss.xml.jssite/rss.xml에 RSS 피드를 생성합니다.

  2. rss() 헬퍼를 @astrojs/rss 패키지에서 .xml.js 파일로 가져와서 다음 매개변수를 사용하여 반환하는 함수를 내보냅니다.

    import rss from '@astrojs/rss';
    
    export function GET(context) {
      return rss({
        // 출력 xml에서의 `<title>` 필드
        title: 'Buzz’s Blog',
        // 출력 xml에서의 `<description>` 필드
        description: 'A humble Astronaut’s guide to the stars',
        // 엔드포인트 컨텍스트에서 프로젝트 "site"를 가져옵니다.
        // https://docs.astro.build/ko/reference/api-reference/#contextsite
        site: context.site,
        // 출력 xml에서의 `<item>` 배열
        // 콘텐츠 컬렉션 및 glob 가져오기를 사용한 예제는 "항목 생성" 섹션을 참조하세요.
        items: [],
        // (선택 사항) 사용자 지정 XML을 삽입할 수도 있습니다.
        customData: `<language>en-us</language>`,
      });
    }

items 필드 생성

items 필드는 getCollection()을 사용하여 콘텐츠 컬렉션 항목에서 또는 pagesGlobToRssItems()를 사용하여 페이지 파일에서 생성할 수 있는 RSS 피드 객체 목록을 허용합니다.

RSS 피드 표준 형식에는 게시된 각 항목에 대해 다음 값이 포함됩니다.

  • title: 항목의 제목입니다. description이 설정된 경우에만 선택사항입니다. 그렇지 않으면 필수입니다.
  • description: 항목의 짧은 발췌 또는 설명입니다. title이 설정된 경우에만 선택사항입니다. 그렇지 않으면 필수입니다.
  • link: 항목의 원본 소스에 대한 URL입니다. (선택사항)
  • pubDate: 항목의 게시 날짜입니다. (선택사항)
  • content: 게시물의 전체 내용입니다. (선택사항)
  • customData: 블로그 게시물의 기타 프런트매터 속성과 같은 추가 데이터를 포함하는 필드입니다.

콘텐츠 컬렉션 사용하기

콘텐츠 컬렉션에서 관리되는 페이지의 RSS 피드를 생성하려면 getCollection() 함수를 사용하여 items 배열에 필요한 데이터를 검색하세요. 반환된 데이터에서 원하는 각 속성 (예: title, description)에 대한 값을 지정해야 합니다.

import rss from '@astrojs/rss';
import { getCollection } from 'astro:content';

export async function GET(context) {
  const blog = await getCollection('blog');
  return rss({
    title: 'Buzz’s Blog',
    description: 'A humble Astronaut’s guide to the stars',
    site: context.site,
    items: blog.map((post) => ({
      title: post.data.title,
      pubDate: post.data.pubDate,
      description: post.data.description,
      customData: post.data.customData,
      // 게시물의 `slug`에서 RSS 링크를 생성합니다
      // 이 예에서는 모든 글이 `/blog/[slug]` 경로로 렌더링된다고 가정합니다.
      link: `/blog/${post.slug}/`,
    })),
  });
}

(선택사항) 기존 블로그 컬렉션 스키마를 교체하여 예상되는 RSS 속성을 적용할 수도 있습니다.

모든 블로그 항목이 유효한 RSS 피드 항목을 생성하도록 하려면 스키마의 각 개별 속성을 정의하는 대신 선택적으로 rssSchema를 가져와 적용할 수 있습니다.

import { defineCollection } from 'astro:content';
import { rssSchema } from '@astrojs/rss';

const blog = defineCollection({
  schema: rssSchema,
});

export const collections = { blog };

Glob Imports 사용하기

src/pages/에 있는 문서에서 RSS 피드를 만들려면 pagesGlobToRssItems() 헬퍼를 사용합니다. 이 함수는 import.meta.glob의 결과를 받아 유효한 RSS 피드 항목 배열을 출력합니다(포함할 페이지를 지정하려면 more about writing glob patterns을 참조하세요).

:::caution 이 기능은 필요한 모든 피드 속성이 각 문서의 프런트 매터에 있다고 가정하지만 확인하지는 않습니다. 오류가 발생하면 각 페이지 프런트 매터를 수동으로 확인해야 합니다. :::

import rss, { pagesGlobToRssItems } from '@astrojs/rss';

export async function GET(context) {
  return rss({
    title: 'Buzz’s Blog',
    description: 'A humble Astronaut’s guide to the stars',
    site: context.site,
    items: await pagesGlobToRssItems(
      import.meta.glob('./blog/*.{md,mdx}'),
    ),
  });
}

:::note[이전 버전을 사용 중이신가요?] v2.1.0 이전 @astrojs/rss 버전에서는 pagesGlobToRssItems() 래퍼 없이 glob 결과를 items로 바로 전달합니다:

items: import.meta.glob('./blog/*.{md,mdx}'),

이 방법은 v2.1.0 이후 모든 Astro 버전에서 더 이상 사용되지 않으며 최신 프로젝트에서는 사용할 수 없습니다. :::

게시물의 전체 콘텐츠 포함하기

content 필드에는 글의 전체 콘텐츠가 HTML로 포함됩니다. 이를 통해 RSS 피드 리더가 전체 글 콘텐츠를 사용할 수 있도록 할 수 있습니다.

:::tip sanitize-html과 같은 패키지는 콘텐츠가 적절하게 삭제되고, 이스케이프되고, 인코딩되었는지 확인합니다. 그 과정에서 이러한 패키지는 일부 무해한 요소와 속성도 제거할 수 있으므로 출력을 확인하고 필요에 따라 패키지를 구성합니다. :::

콘텐츠 컬렉션을 사용할 때 markdown-it과 같은 표준 Markdown 파서를 사용하여 콘텐츠를 렌더링할 때 필요한 추가 태그 (예: <img>)를 포함하여 게시물의 body를 렌더링하고 결과를 정리합니다.

import rss from '@astrojs/rss';
import { getCollection } from 'astro:content';
import sanitizeHtml from 'sanitize-html';
import MarkdownIt from 'markdown-it';
const parser = new MarkdownIt();

export async function GET(context) {
  const blog = await getCollection('blog');
  return rss({
    title: 'Buzz’s Blog',
    description: 'A humble Astronaut’s guide to the stars',
    site: context.site,
    items: blog.map((post) => ({
      link: `/blog/${post.slug}/`,
      // 참고: MDX 파일에서 컴포넌트나 JSX는 처리하지 않습니다.
      content: sanitizeHtml(parser.render(post.body), {
        allowedTags: sanitizeHtml.defaults.allowedTags.concat(['img'])
      }),
      ...post.data,
    })),
  });
}

마크다운과 함께 글로브 가져오기를 사용하는 경우, compiledContent() 헬퍼를 사용하여 이스케이프 처리를 위해 렌더링된 HTML을 검색할 수 있습니다. 참고로 이 기능은 MDX 파일에는 지원되지 않습니다.

import rss from '@astrojs/rss';
import sanitizeHtml from 'sanitize-html';

export function GET(context) {
  const postImportResult = import.meta.glob('../posts/**/*.md', { eager: true }); 
  const posts = Object.values(postImportResult);
  return rss({
    title: 'Buzz’s Blog',
    description: 'A humble Astronaut’s guide to the stars',
    site: context.site,
    items: posts.map((post) => ({
      link: post.url,
      content: sanitizeHtml(post.compiledContent()),
      ...post.frontmatter,
    })),
  });
}

후행 슬래시 제거

Astro의 RSS 피드는 trailingSlash에 대해 구성한 값에 관계없이 기본적으로 후행 슬래시가 있는 링크를 생성합니다. 이는 RSS 링크가 게시물 URL과 정확하게 일치하지 않을 수 있음을 의미합니다.

astro.config.mjs 파일에서 trailingSlash: "never"를 설정한 경우, 피드가 프로젝트 구성과 일치하도록 rss() 도우미에서 trailingSlash: false를 설정하세요.

import rss from '@astrojs/rss';

export function GET(context) {
  const posts = Object.values(postImportResult);
  return rss({
    title: 'Buzz’s Blog',
    description: 'A humble Astronaut’s guide to the stars',
    site: context.site,
    trailingSlash: false,
    items: posts.map((post) => ({
      link: post.url,
      ...post.frontmatter,
    })),
  });
}

스타일시트 추가하기

브라우저에서 파일을 볼 때 더욱 쾌적한 사용자 환경을 위해 RSS 피드에 스타일을 지정할 수도 있습니다.

rss 함수의 stylesheet 옵션을 사용하여 스타일시트의 절대 경로를 지정할 수 있습니다.

rss({
  // 예: "public/rss/styles.xsl"의 스타일시트 사용하기
  stylesheet: '/rss/styles.xsl',
  // ...
});

:::tip 직접 스타일시트를 만들고 싶지 않다면 Pretty Feed v3 기본 스타일시트와 같은 미리 만들어진 스타일시트를 사용할 수 있습니다. GitHub에서 스타일시트를 다운로드하여 프로젝트의 public/ 디렉터리에 저장합니다. :::

RSS 피드 자동 검색 활성화

RSS autodiscovery를 사용하면 브라우저 및 기타 소프트웨어가 자동으로 기본 URL에서 사이트의 RSS 피드를 찾을 수 있습니다.

활성화하려면 사이트의 head 요소에 다음 속성이 포함된 <link> 태그를 추가하세요.

<link
    rel="alternate"
    type="application/rss+xml"
    title="Your Site's Title"
    href={`${Astro.site}rss.xml`}
/>

이 태그를 사용하면 블로그 독자가 RSS 리더에 사이트의 기본 URL을 입력하여 RSS 피드의 특정 URL 없이 게시물을 구독할 수 있습니다.

다음 단계

브라우저에서 your-domain.com/rss.xml에서 피드를 방문하여 각 글에 대한 데이터를 볼 수 있는지 확인한 후 이제 웹사이트에서 피드를 홍보할 수 있습니다. 사이트에 표준 RSS 아이콘을 추가하면 독자가 자신의 피드 리더에서 내 글을 구독할 수 있음을 알 수 있습니다.

자료