Skip to content

Support JSON feed version 1.1 - #247

Open
Kiwow wants to merge 10 commits into
jpmonette:mainfrom
Kiwow:json-feed-1.1
Open

Support JSON feed version 1.1#247
Kiwow wants to merge 10 commits into
jpmonette:mainfrom
Kiwow:json-feed-1.1

Conversation

@Kiwow

@Kiwow Kiwow commented Jun 5, 2026

Copy link
Copy Markdown

Closes #246

Thanks for your hard work maintaining this! I had a go at implementing support for the JSON feed version 1.1 spec.

I've added:

  • support for multiple authors for both feeds and items. In the case that a single author is provided, we convert it into a 1-item array and use it in the "authors" field, because the spec has deprecated "author" and recommends only using the array field.
  • support for the "language" field for both feeds and items
  • declaration of the 1.1 feed version
  • tests that fail without this PR and succeed with it
  • workaround for multiple feed authors for RSS and Atom - to implement multiple feed authors for JSON feed, I changed the type of FeedOptions.author to include an array of authors. When multiple feed authors are provided, I've made it so that only the first one is used in case of RSS and Atom. This could be addressed in the future, although I'm not sure about how/if RSS and Atom support multiple feed authors

I'm not sure if provided contributors should be merged into the authors array, but I haven't done so yet. In the (current) version 1 implementation, contributors are ignored for JSON feed as well. If it makes sense to you to merge contributors in, I don't have a problem with adding that bit.

Comment thread src/atom1.ts Outdated
Comment thread src/json.ts Outdated
if (options.author.avatar) {
feed.author.avatar = options.author.avatar;
}
feed.authors = toArray(options.author).map((author) => ({

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
feed.authors = toArray(options.author).map((author) => ({
feed.authors = (Array.isArray(options.author) ? options.author : [options.author]).map((author) => ({

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've switched the implementation to use both a author and authors property for the feed options, but I've essentially made this change, it's just checking for the different properties instead of checking if one is an array

Comment thread src/utils.ts
Comment thread src/rss2.ts Outdated
Comment on lines +31 to +33
if (options.author && Array.isArray(options.author)) {
options.author = options.author[0];
}

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm skeptical this is valid - can you provide a reference?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After researching this, multiple authors in RSS is a huge mess. It took me a while to notice that this library only renders feed author in the case of podcasts. Because of that, I think it's enough to fallback to the first authors in case multiple are specified.

Comment thread src/json.ts
Comment on lines 80 to +85
if (item.author) {
let author: Author | Author[] = item.author;
if (author instanceof Array) {
// json feed only supports 1 author per post
author = author[0];
}
feedItem.author = {};
if (author.name) {
feedItem.author.name = author.name;
}
if (author.link) {
feedItem.author.url = author.link;
}
if (author.avatar) {
feedItem.author.avatar = author.avatar;
}
feedItem.authors = item.author.map((author) => ({
name: author.name,
url: author.link,
avatar: author.avatar,
}));

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you preserve existing behavior if 1.0 is used, to be backward compatible? Same for the one at the top-level.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I've done this. item.author is already an array and I've updated my changes so that feed.author is always a single author. For multiple authors, I've added an FeedOptions.authors property like you suggested in a comment below. So if you decide to merge this it should be able to come out as a minor, because the library's API is the same as before and behavior is the same for the same inputs.

Unless I'm misunderstanding and you mean we should have options for generating both a JSON Feed 1.0 and 1.1. In that sense, my changes aren't backwards compatible, because they always create a 1.1 feed. I assumed readers generally support 1.1 since it's almost 6 years old now, but I might be wrong.

Comment thread src/atom1.ts Outdated
Comment on lines +39 to +40
if (options.author) {
base.feed.author = formatAuthor(options.author);
base.feed.author = formatAuthor(Array.isArray(options.author) ? options.author[0] : options.author);

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd expect this change to be covered in tests?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right, sorry. I realized Atom supports multiple authors so that's what I implemented instead, and I added a test to verify that my implementation works. Let me know what you think

Comment thread src/typings/index.ts Outdated
category?: string;

author?: Author;
author?: Author | Author[];

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
author?: Author | Author[];
/**
* @deprecated Use authors instead. This will be removed in next major.
*/
author?: Author;
authors?: Author[];

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is way nicer than what I did originally. I changed the deprecation comment a bit, but otherwise I've done this

Comment thread src/__tests__/setup.ts Outdated
Comment on lines +6 to +9
export const createSampleFeed = ({
authors,
itemAuthors,
}: Partial<{ authors: FeedOptions["author"]; itemAuthors: Item["author"] }> = {}) => {

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we restore original APi?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As noted in a previous comment, I ended up keeping FeedOptions.author the same and added a FeedOptions.authors property. If I'm understanding correctly, that keeps the library API the same.

I hope it's okay that I added some optional helper arguments to the createSampleFeed function to make some tests nicer, which is what is present in this diff. Those arguments now reflect FeedOptions["authors"]

Comment thread src/typings/index.ts
id?: string;
link: string;
date: Date;
language?: string;

@jpmonette jpmonette Jun 26, 2026

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Atom seems to support this as well, so please make sure it's added to the entries.

Could you also do a loose validation that it is ISO 639-1? Combination of lowercase + /^[a-z]{2}(-[a-z]{2})?$/.test(code).

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point, thanks. I added a validateLanguageCode utility to be used when adding language to JSON feeds and the xml:lang attribute in Atom.

@jpmonette

Copy link
Copy Markdown
Owner

@Kiwow Thanks for the contribution - please address the review.

@Kiwow

Kiwow commented Jul 14, 2026

Copy link
Copy Markdown
Author

@Kiwow Thanks for the contribution - please address the review.

Thanks for the review @jpmonette! Sorry about the time it took me to respond. I've found some time for open source again, so I should be more responsive now.

I changed the PR quite a bit based on your feedback. Please let me know what you think / if I misunderstood anything. There's also a few seemingly unrelated changes caused by the move to vitest and biome.

P.S. Don't be fooled by GitHub saying I added the new commits five days ago. I just pushed them

@Kiwow
Kiwow requested a review from jpmonette July 14, 2026 21:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

JSON Feed 1.1

3 participants