{"id":27919460,"url":"https://github.com/flcdrg/astrojs-atom","last_synced_at":"2026-04-17T07:01:21.345Z","repository":{"id":288567797,"uuid":"968039756","full_name":"flcdrg/astrojs-atom","owner":"flcdrg","description":"RSS Atom for Astro","archived":false,"fork":false,"pushed_at":"2026-04-14T04:45:34.000Z","size":929,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-04-14T06:27:47.365Z","etag":null,"topics":["astrojs","atom-feed","rss"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/flcdrg.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"github":"flcdrg"}},"created_at":"2025-04-17T12:05:59.000Z","updated_at":"2026-04-14T04:45:38.000Z","dependencies_parsed_at":"2025-05-06T19:38:56.883Z","dependency_job_id":"df171e7a-1372-4499-81b7-bd5e3d0c20df","html_url":"https://github.com/flcdrg/astrojs-atom","commit_stats":null,"previous_names":["flcdrg/astro-atom","flcdrg/astrojs-atom"],"tags_count":26,"template":false,"template_full_name":null,"purl":"pkg:github/flcdrg/astrojs-atom","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/flcdrg%2Fastrojs-atom","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/flcdrg%2Fastrojs-atom/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/flcdrg%2Fastrojs-atom/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/flcdrg%2Fastrojs-atom/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/flcdrg","download_url":"https://codeload.github.com/flcdrg/astrojs-atom/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/flcdrg%2Fastrojs-atom/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31918838,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-16T18:22:33.417Z","status":"online","status_checked_at":"2026-04-17T02:00:06.879Z","response_time":62,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["astrojs","atom-feed","rss"],"created_at":"2025-05-06T19:30:59.588Z","updated_at":"2026-04-17T07:01:21.335Z","avatar_url":"https://github.com/flcdrg.png","language":"TypeScript","funding_links":["https://github.com/sponsors/flcdrg"],"categories":[],"sub_categories":[],"readme":"# astrojs-atom\n\n![NPM Version](https://img.shields.io/npm/v/astrojs-atom)\n\nA library for generating [Atom syndication feeds](https://validator.w3.org/feed/docs/atom.html) in Astro projects. This is a fork of `@astrojs/rss` that implements the Atom feed format instead of RSS.\n\n## Compatibility\n\n- Astro `6.x`\n- Node `22.12.0` or newer\n\n## Installation\n\n```bash\n# Using npm\nnpm install astrojs-atom\n\n# Using yarn\nyarn add astrojs-atom\n\n# Using pnpm\npnpm install astrojs-atom\n```\n\nThis package uses `astro/zod`, so its schema behavior follows the Zod version bundled with your installed Astro version. With Astro 6, that means Zod 4 semantics.\n\n## Usage\n\nCreate a new `.xml.js` or `.xml.ts` file in your Astro pages directory to generate an Atom feed:\n\n```typescript\n// src/pages/atom.xml.js\nimport { getAtomResponse } from 'astrojs-atom';\n\nexport async function GET(context) {\n  return getAtomResponse({\n    // Required: Feed metadata\n    title: \"My Website\",\n    id: \"https://example.com/\",\n    updated: new Date().toISOString(),\n    \n    // Required: Array of feed entries\n    entry: [\n      {\n        title: \"My First Article\",\n        id: \"https://example.com/blog/first-article\",\n        updated: \"2023-01-01T00:00:00Z\",\n        // Optional: content, author, link, etc.\n        content: \"This is my first article.\",\n        link: [\n          { href: \"https://example.com/blog/first-article\", rel: \"alternate\" }\n        ]\n      }\n    ],\n    \n    // Optional: Customize the feed with additional properties\n    subtitle: \"My Personal Blog\",\n    lang: \"en-US\",\n    author: [\n      { \n        name: \"Your Name\",\n        email: \"you@example.com\"\n      }\n    ],\n    // Add custom stylesheet\n    stylesheet: \"/atom-styles.xsl\"\n  });\n}\n```\n\n## API Reference\n\n### Main Functions\n\n- `getAtomResponse`: Returns a `Response` object with the Atom XML and an Atom-specific `Content-Type` header\n- `getAtomString`: Returns just the XML string without creating a Response object\n\n### Feed Options (AtomFeedOptions)\n\n#### Required Properties\n\n| Property | Type | Description |\n|----------|------|-------------|\n| `title` | `string` or `object` | Title of the feed. Can be a simple string or an object with `value` and `type` attributes |\n| `id` | `string` | Unique identifier for the feed (typically your site URL) |\n| `updated` | `string` | Last updated timestamp (RFC 3339 format) |\n| `entry` | `Array` | Array of feed entries |\n\n#### Optional Properties\n\n| Property | Type | Description |\n|----------|------|-------------|\n| `subtitle` | `string` or `object` | Description or subtitle for the feed as an Atom text construct |\n| `author` | `Array` | Feed authors as an array of person objects |\n| `link` | `Array` | Links related to the feed |\n| `category` | `Array` | Categories for the feed |\n| `contributor` | `Array` | Contributors to the feed |\n| `generator` | `object` | Information about the generator of the feed |\n| `icon` | `string` | URL to an icon for the feed |\n| `logo` | `string` | URL to a logo for the feed |\n| `rights` | `string` or `object` | Copyright information |\n| `lang` | `string` | Language of the feed (sets xml:lang attribute) |\n| `xmlns` | `object` | Custom XML namespaces to include |\n| `stylesheet` | `string` | URL to an XSL stylesheet |\n| `useLegacyXmlContentType` | `boolean` | Makes `getAtomResponse()` use the legacy `application/xml; charset=utf-8` header instead of the default Atom media type |\n| `sortEntriesByUpdated` | `boolean` | When `true`, sorts entries by `updated` descending before serialization. By default, entry order is preserved as provided |\n| `customData` | `string` | Custom XML to include in the feed |\n\n`getAtomResponse()` now returns `Content-Type: application/atom+xml; charset=utf-8` by default. If you need the previous header for compatibility with an existing consumer, set `useLegacyXmlContentType: true`.\n\nFeed entries preserve the input order by default. If you want the previous behavior of sorting entries by `updated` descending during generation, set `sortEntriesByUpdated: true`.\n\n### Entry Properties\n\nEach entry in the `entry` array can have the following properties:\n\n#### Required Properties\n\n| Property | Type | Description |\n|----------|------|-------------|\n| `title` | `string` or `object` | Title of the entry |\n| `id` | `string` | Unique identifier for the entry |\n| `updated` | `string` | Last updated timestamp (RFC 3339 format) |\n\n#### Optional Properties\n\n| Property | Type | Description |\n|----------|------|-------------|\n| `author` | `Array` | Entry authors |\n| `content` | `string` or `object` | Full content of the entry. Object content can either provide an inline `value` or an external `src`, plus optional `type` and explicit `base` values |\n| `link` | `Array` | Links related to the entry |\n| `summary` | `string` or `object` | Summary of the entry |\n| `category` | `Array` | Categories for the entry |\n| `contributor` | `Array` | Contributors to the entry |\n| `published` | `string` | Publication date (RFC 3339 format) |\n| `rights` | `string` or `object` | Entry-specific copyright information |\n| `source` | `object` | Source feed information for republished entries. Shared Atom metadata inside `source` uses the same construct handling as the feed, including text constructs for `title`, `subtitle`, and `rights` |\n| `customData` | `string` | Custom XML to include in the entry |\n| `thumbnail` | `object` | Thumbnail image for the entry |\n\n## Text Constructs (title, subtitle, summary, rights)\n\nFor properties like `title`, `subtitle`, `summary`, and `rights`, you can use either:\n\n- A simple string: `title: \"My Title\"`\n- An object with attributes: `title: { value: \"My Title\", type: \"html\" }`\n\n## Type Attribute Values\n\nCommon `type` attribute values include:\n\n- `\"text\"` (default) - Plain text\n- `\"html\"` - Serialized as entity-escaped HTML\n- `\"xhtml\"` - Serialized as inline XHTML wrapped in `\u003cdiv xmlns=\"http://www.w3.org/1999/xhtml\"\u003e`\n- XML media types such as `\"application/xml\"` or `\"image/svg+xml\"` - Serialized inline as XML\n- Other non-text media types - Serialized as base64-encoded content\n\nFor Atom text constructs such as `title`, `summary`, and `rights`, use `text`, `html`, or `xhtml`.\n\n## Examples\n\n### Entry with HTML Content\n\n```typescript\n{\n  title: \"My Article\",\n  id: \"https://example.com/blog/my-article\",\n  updated: \"2023-01-01T00:00:00Z\",\n  content: {\n    type: \"html\",\n    value: \"\u003cp\u003eThis is \u003cstrong\u003eformatted\u003c/strong\u003e content.\u003c/p\u003e\"\n  }\n}\n```\n\nThis generates escaped HTML inside the Atom element body, not CDATA:\n\n```xml\n\u003ccontent type=\"html\"\u003e\u0026lt;p\u0026gt;This is \u0026lt;strong\u0026gt;formatted\u0026lt;/strong\u0026gt; content.\u0026lt;/p\u0026gt;\u003c/content\u003e\n```\n\n### Entry with XHTML Content\n\n```typescript\n{\n  title: {\n    type: \"xhtml\",\n    value: \"\u003cp\u003eThis is \u003cstrong\u003eXHTML\u003c/strong\u003e content.\u003c/p\u003e\"\n  },\n  id: \"https://example.com/blog/xhtml-article\",\n  updated: \"2023-01-01T00:00:00Z\",\n  content: {\n    type: \"xhtml\",\n    value: \"\u003cp\u003eThis is \u003cstrong\u003eXHTML\u003c/strong\u003e content.\u003c/p\u003e\"\n  }\n}\n```\n\nThis generates inline XHTML wrapped in the required XHTML `div`:\n\n```xml\n\u003ccontent type=\"xhtml\"\u003e\n  \u003cdiv xmlns=\"http://www.w3.org/1999/xhtml\"\u003e\n    \u003cp\u003eThis is \u003cstrong\u003eXHTML\u003c/strong\u003e content.\u003c/p\u003e\n  \u003c/div\u003e\n\u003c/content\u003e\n```\n\n### Entry with External Content\n\n```typescript\n{\n  title: \"Hosted Elsewhere\",\n  id: \"https://example.com/blog/hosted-elsewhere\",\n  updated: \"2023-01-01T00:00:00Z\",\n  summary: \"Read the full article at the source URL.\",\n  content: {\n    src: \"https://example.com/content/hosted-elsewhere.html\",\n    type: \"text/html\"\n  }\n}\n```\n\nWhen `src` is present, the content is linked externally and no inline `value` is allowed:\n\n```xml\n\u003ccontent src=\"https://example.com/content/hosted-elsewhere.html\" type=\"text/html\" /\u003e\n```\n\n`xml:base` is no longer added automatically to every `\u003ccontent\u003e` element. If you need it for relative IRI resolution, use object-form content and pass an explicit `base` value:\n\n```typescript\n{\n  content: {\n    value: \"\u003cp\u003eBody\u003c/p\u003e\",\n    type: \"html\",\n    base: \"https://cdn.example.com/articles/\"\n  }\n}\n```\n\n### Using Custom XML Namespaces\n\n```typescript\ngetAtomResponse({\n  // ...feed options\n  xmlns: {\n    \"dc\": \"http://purl.org/dc/elements/1.1/\",\n    \"georss\": \"http://www.georss.org/georss\"\n  },\n  entry: [\n    {\n      // ...entry properties\n      customData: '\u003cdc:creator\u003eJohn Smith\u003c/dc:creator\u003e\u003cgeorss:point\u003e45.256 -71.92\u003c/georss:point\u003e'\n    }\n  ]\n});\n```\n\n## Media Content\n\nThe Atom feed generator supports adding media elements to entries using the Yahoo Media RSS extension.\n\n### Adding Thumbnails\n\nYou can add thumbnail images to entries with the `thumbnail` property:\n\n```typescript\n{\n  // ...other entry properties\n  thumbnail: {\n    url: \"https://example.com/images/thumbnail.jpg\",\n    medium: \"image\", // Optional, defaults to \"image\"\n    width: 300,      // Optional\n    height: 200      // Optional\n  }\n}\n```\n\nThis will generate both `media:thumbnail` and `media:content` elements in your feed:\n\n```xml\n\u003cfeed xmlns=\"http://www.w3.org/2005/Atom\" xmlns:media=\"http://search.yahoo.com/mrss/\"\u003e\n  \u003cmedia:thumbnail\n  url=\"https://example.com/images/thumbnail.jpg\"\n  width=\"300\" height=\"200\" /\u003e\n  \u003cmedia:content medium=\"image\"\n  url=\"https://example.com/images/thumbnail.jpg\"\n  width=\"300\" height=\"200\" /\u003e\n\u003c/feed\u003e\n```\n\nThe Media RSS namespace (`xmlns:media=\"http://search.yahoo.com/mrss/\"`) is automatically added once at the feed level when a thumbnail is included.\n\n## Validation\n\nTo validate your Atom feed, use the [W3C Feed Validation Service](https://validator.w3.org/feed/).\n\nThe library also validates Atom date-time fields against RFC 3339 during schema parsing. `feed.updated`, `entry.updated`, `entry.published`, and `source.updated` must include a full date-time with either `Z` or an explicit UTC offset.\n\nURI-based Atom fields such as `link.href`, `author.uri`, `generator.uri`, and `content.src` accept Atom-compatible URI or URI-reference values like `urn:uuid:...` and `/feed`, not just absolute URLs.\n\nAtom `link.length` values are validated as non-negative byte counts. You can pass either a number like `1234` or a numeric string like `\"1234\"`.\n\nAtom author requirements are also validated across the whole feed: if the feed has no top-level `author`, then every entry must provide author data either directly on the entry or through its `source`.\n\n`entry.source` metadata is serialized with the same Atom construct mappings as top-level feed metadata, so `source.title`, `source.subtitle`, and `source.rights` support text constructs, while `source.link`, `source.category`, and `source.generator` serialize using Atom attribute/value conventions.\n\nAtom content no longer emits `xml:base` automatically from `entry.id`. If you need `xml:base`, set `content.base` explicitly on object-form content.\n````\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fflcdrg%2Fastrojs-atom","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fflcdrg%2Fastrojs-atom","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fflcdrg%2Fastrojs-atom/lists"}