2025-06-17 10:49:42 -05:00
2025-06-17 10:37:43 -05:00
2025-06-17 10:04:42 -05:00
2025-06-17 10:04:42 -05:00
2025-06-17 10:00:32 -05:00
2025-06-17 10:04:42 -05:00
2025-06-17 10:00:32 -05:00
2025-06-17 10:23:33 -05:00
2025-06-17 10:49:42 -05:00
2025-06-17 10:04:42 -05:00

Podcast RSS Generator

A simple, data-agnostic JavaScript utility to generate a valid podcast RSS 2.0 feed from your own data objects.

Core Concept: Server vs. Browser

This package is a JavaScript utility that can run anywhere. However, a real podcast feed must be a publicly accessible file on a server. Podcast platforms like Spotify and Apple Podcasts need a static URL to check for new episodes.

This means the correct way to use this library is in a server-side environment like a Next.js API Route or an Express backend.

We have also included a Pure React example for demonstration purposes, showing how the library can be run in the browser to view or download the feed manually.

Installation

npm install podcast-rss

How It Works

The package exports a single function, generatePodcastRss. You provide it with your show's data, and it returns the complete XML feed as a string.

import { generatePodcastRss } from 'podcast-rss-generator-js';

const feed = generatePodcastRss(podcast, episodes, options);

API Reference: Complete List of Options

Podcast Object Options

This object contains all the channel-level information for your podcast.

Key Type Required? Description
title string Required The name of your podcast.
description string Required A short description or summary of the show.
image_url string Required URL to the podcast's square cover art (JPG/PNG, 1400x1400 to 3000x3000 pixels).
podcast_slug string Required The URL-friendly slug used to build the feed's link.
owner string Required The author or host of the podcast. Used for <itunes:author>.
itunes_owner_name string Required The name of the podcast owner. Displayed in podcast clients.
itunes_owner_email string Required The email of the podcast owner. Used for verification.
itunes_category Array<object> Required An array of category objects. Ex: [{ text: 'Technology' }] or [{ text: 'Business', subtext: 'Careers' }].
id string Required A unique identifier for the podcast itself. Used for <podcast:guid>. A UUID is recommended.
created_at Date or string Required The date the podcast was created. Used for <pubDate>.
explicit boolean Required true if the podcast contains explicit content, otherwise false.
language string Optional The two-letter ISO language code (e.g., en, es). Defaults to en-us.
updated_at Date or string Optional The date the podcast was last updated. Defaults to created_at.
locked 'yes' or 'no' Optional Whether the podcast is locked from being imported elsewhere. Defaults to 'no'.

Episode Object Options

This is an array of objects, where each object represents a single episode.

Key Type Required? Description
guid string Required A globally unique and permanent identifier for the episode. Using the audio file URL is not recommended. Use a UUID.
title string Required The title of the episode.
description string Required The episode's show notes. Can contain HTML.
publication_date Date or string Required The date the episode was published.
audio_url string Required The direct URL to the episode's audio file (e.g., .mp3, .m4a).
audio_length number Required The size of the audio file in bytes.
episode_slug string Required The URL-friendly slug for the episode page.
image_url string Optional URL to episode-specific cover art. Overrides the main podcast image.

Usage Examples

This is the ideal approach for modern React projects.

File: app/podcasts/[slug]/rss.xml/route.js

import { NextResponse } from 'next/server';
import { generatePodcastRss } from 'podcast-rss-generator-js';

export async function GET(request, { params }) {
  // In a real app, you would fetch this data from a database or CMS.
  const podcastData = {
    title: 'My Awesome Podcast',
    description: 'A show about awesome things.',
    image_url: 'https://example.com/images/cover.png',
    podcast_slug: params.slug,
    owner: 'Jane Doe',
    itunes_owner_name: 'Jane Doe',
    itunes_owner_email: '[email protected]',
    itunes_category: [{ text: 'Technology' }],
    id: 'a8b7c6d5-e4f3-a2b1-c0d9-e8f7a6b5c4d3',
    created_at: new Date(),
    explicit: false,
  };
  const episodes = [{
    guid: 'unique-episode-id-123',
    title: 'Our First Episode!',
    description: 'The description for our first episode.',
    publication_date: new Date(),
    audio_url: 'https://example.com/audio/ep1.mp3',
    audio_length: 34216300, // in bytes
    episode_slug: 'our-first-episode',
  }];

  const rssFeed = generatePodcastRss(podcastData, episodes, {
    siteUrl: 'https://www.example.com',
  });

  return new NextResponse(rssFeed, {
    status: 200,
    headers: { 'Content-Type': 'application/rss+xml' },
  });
}

Example 2: Client-Side Demonstration

⚠️ Important: This example is for demonstration only. A podcast feed generated this way cannot be submitted to Spotify or Apple Podcasts because it does not have a permanent public URL. It only exists inside your user's browser.

This component shows how to run the generator in the browser and lets the user view or download the output.

File: src/PodcastGeneratorComponent.js

import React, { useState } from 'react';
import { generatePodcastRss } from 'podcast-rss-generator-js';

// --- Hardcode data for the demo ---
const podcastData = {
  title: 'My React Podcast',
  description: 'A demo podcast generated entirely in the browser.',
  image_url: 'https://example.com/images/cover.png',
  podcast_slug: 'my-react-podcast',
  owner: 'React Developer',
  itunes_owner_name: 'React Developer',
  itunes_owner_email: '[email protected]',
  itunes_category: [{ text: 'Technology' }],
  id: 'a8b7c6d5-e4f3-a2b1-c0d9-e8f7a6b5c4d4',
  created_at: new Date(),
  explicit: false,
};
const episodes = [{
  guid: 'demo-episode-1',
  title: 'Hello, React!',
  description: 'This episode was generated by a React component.',
  publication_date: new Date(),
  audio_url: 'https://example.com/audio/ep1.mp3',
  audio_length: 34216300,
  episode_slug: 'hello-react',
}];

function PodcastGeneratorComponent() {
  const [rssText, setRssText] = useState('');
  const [downloadLink, setDownloadLink] = useState('');

  const handleGenerateRss = () => {
    const feed = generatePodcastRss(podcastData, episodes, {
      siteUrl: 'https://www.example.com',
    });
    setRssText(feed);

    const blob = new Blob([feed], { type: 'application/rss+xml' });
    setDownloadLink(URL.createObjectURL(blob));
  };

  return (
    <div style={{ fontFamily: 'sans-serif', border: '1px solid #ccc', padding: '20px', borderRadius: '8px' }}>
      <h2>Podcast Feed Generator (Client-Side Demo)</h2>
      <p>Click the button to generate the XML feed inside the browser.</p>
      <button onClick={handleGenerateRss} style={{ padding: '10px 15px', marginBottom: '20px' }}>
        Generate RSS Feed
      </button>

      {rssText && (
        <div>
          <h3>Generated XML Output:</h3>
          <textarea
            readOnly
            value={rssText}
            style={{ width: '95%', height: '250px' }}
          />
          <br />
          <a
            href={downloadLink}
            download="rss.xml"
            style={{ display: 'inline-block', marginTop: '10px' }}
          >
            Download rss.xml file
          </a>
        </div>
      )}
    </div>
  );
}

export default PodcastGeneratorComponent;
S
Description
No description provided
Readme MIT
59 KiB
Languages
JavaScript 100%