Unique RSS feed urls for websites with Localized add-on

Hello.

Has anyone found a way to create CMS Collection RSS feeds with the Localization add-on on sub-locales?

We have Localization on, but it limits feeds only to primary locale. So we can’t get a feed for the blog or any other CMS Collection on any of other 3 sub-locales (upgrade to Enterprise is not an option for us at this stage).

I tried https://rss.app/ to spin up a Feed, but that ignores pagination and picks only the first 9 posts. Does anyone know a better platform/tool?

Please, upvote at the wishlist here if you also need those capabilities in Webflow - Unique RSS feed urls for localized websites | Webflow Wishlist.

I haven’t needed to do this on a localized site, but when I need a specialized RSS feed, I drop some collection lists on a hidden page, tag the elements with custom attributes, and use a cloudflare worker to generate RSS from that.

It’s pretty straightforward and lets me do things like category-specific filtering, podcast-specific feeds with media references, MRSS, excerpted HTML from rich text, merged RSS feeds from multiple collections, etc. very creative client-specific stuff, without an added monthly fee.

You could definitely do a localized feed this way.

Thanks for the suggestion, @memetican .
I’m looking into Cloudflare and trying different things with ChatGPT, but keep getting errors related to parsers. There seem to be many but I still can’t find a setup that works. Even HTMLRewriter which is supposed to work by default gives me “Cannot find name ‘HTMLRewriter’”. Can you recommend what’s your go-to setup?

Had a breakthrough with HTMLRewriter and exactly as you suggested attributes was the secret, rather than trying to parse the dom and get textContent.
I will share complete solution once done, so others can benefit from it.

1 Like

Here is the Cloudflare Worker code that made it work for me:

export default {
	async fetch(request) {
		const url = 'https://www.webflow-site.com/us/hidden-page';
		const response = await fetch(url);
		const rewriter = new HTMLRewriter();

		// Define arrays to store extracted data
		let posts = [];

		let currentPost = { link: '', title: '', pubDate: '' };

		rewriter
			.on('.box-card', {
				element(element) {
					currentPost.link = element.getAttribute('rss-href');
				},
			})
			.on('h2', {
				element(element) {
					currentPost.title = element.getAttribute('rss-title');
				},
			})
			.on('.date-thumb-inline', {
				element(element) {
					currentPost.pubDate = element.getAttribute('rss-publish');
					posts.push({ ...currentPost });
					currentPost = { title: '', pubDate: '', link: '' }; // Reset for next post
				},
			});

		// Parse the response
		await rewriter.transform(response).text();

		// Construct XML
		let xmlOutput = `<?xml version="1.0" encoding="UTF-8"?>\n<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/">\n<channel>\n`;
		for (let post of posts) {
			xmlOutput += `<item>\n`;
			xmlOutput += `<title>${post.title}</title>\n`;
			xmlOutput += `<pubDate>${post.pubDate}</pubDate>\n`;
			xmlOutput += `<link>https://www.webflow-site.com${post.link}</link>\n`;
			xmlOutput += `</item>\n`;
		}
		xmlOutput += `</channel>\n</rss>`;

		// Return the XML response
		return new Response(xmlOutput, {
			headers: { 'Content-Type': 'application/xml' },
		});
	},
};

Then I have a Zappier workflow where I check for new items, and update a Google Sheet and post to Slack. Hope this helps to anyone who might go down the same route in solving the RSS issues with localizations.

And once again, I had to go down that route because Zappier has a very limited integration with Webflow with only 3 available triggers. Another platform called Pipedream had all triggers (including collection_item_created), but both don’t recognize the difference in collections related to the Localization add-on.

Nice work, and the array was a nice way to handle it.

If you wanted to take this further, the are a couple of tweaks you can make to make it more reusable. The main one I’d do is to build the worker and worker route so that it is designed to respond to a pattern like *.xml.

Then, the first thing the worker does is strip that .xml and fetch the underlying page as the RSS source material. That way you can easily attach it anywhere.

This gives you some flexibility, suppose you have /blog, you can create a static page /blog/rss which is hidden ( not in the sitemap/ robots noindex ), and which contains all of your blog post RSS content. 20 collection lists gives you up to 2000 posts in that one page.

Then /blog/rss.xml would trigger your worker due to the *.xml route, and easily obtain all 2000 posts to build the feed with.

With localization, you’d automatically also get feeds at /fr/blog/rss.xml, /jp/blog/rss.xml, etc.