HamptonNorth
HamptonNorth

Reputation: 559

Adding an RSS feed to a Sveltekit site with adapter-static set up

I have used Svelte/Sveltekit to develop a personal static blog. This is SSR using adatpter-static with a fallback set and prerender = true added to my root layout.

All went well and Svelte seemed natural, mdsvex worked fine and being able to embed svelte components in my markdown solved any perceived limitation of using Markdown files for content.

My issue comes from trying to add a RSS feed.

I added:

<head>
    .
    
    <link rel="alternate" type="application/atom+xml" href="/feed" />
    
    .
  </head>

and in +server.js at the /src/routes/feed level

import * as config from '$lib/config'
export async function GET({ fetch }) {
  const response = await fetch('api/posts')
  const posts = await response.json()
  const headers = { 'Content-Type': 'application/xml' }

  const xml = `
        <rss xmlns:atom="http://www.w3.org/2005/Atom" version="2.0">
            <channel>
                <title>${config.title}</title>
                <description>${config.description}</description>
                <link>${config.url}</link>
                <atom:link href="${config.url}feed" rel="self" type="application/rss+xml"/>
                ${posts
          .map(
            post => `
                        <item>
                            <title>${post.title}</title>                            
                            <description>${post.description}</description>
                            <link>${config.url}${post.slug.slice(1)}</link>
                            <guid isPermaLink="true">${config.url}${post.slug.slice(1)}</guid>
                            <pubDate>${new Date(post.date).toUTCString()}</pubDate>
                        </item>
                    `          )
          .join('')}
            </channel>
        </rss>
    `.trim()
  return new Response(xml, { headers })
}

From npm run dev and following a build npm run preview return the expected RSS feed xml from /feed:

<rss xmlns:atom="http://www.w3.org/2005/Atom" version="2.0">
    <channel>
        <title>Rants</title>
        <description>Articles expressing inner rage</description>
        <link>https://rants.redmug.dev/</link>
        <atom:link href="https://rants.redmug.dev/feed" rel="self" type="application/rss+xml"/>
        <item>
            <title>Post One test</title>
            <description>Test file for posts to HTML using mdsvex</description>
            <link>https://rants.redmug.dev/posts/post1</link>
            <guid isPermaLink="true">https://rants.redmug.dev/posts/post1</guid>
            <pubDate>Sun, 26 Jan 2025 00:00:00 GMT</pubDate>
        </item>
        <item>
            <title>Test pre processed markdown</title>
            <description>Test file for testing the mdsvex </description>
            <link>https://rants.redmug.dev/posts/test</link>
            <guid isPermaLink="true">https://rants.redmug.dev/posts/test</guid>
            <pubDate>Thu, 26 Dec 2024 00:00:00 GMT</pubDate>
        </item>
    </channel>
</rss>

As soon as I deploy to a production server (Ubuntu + Apache2) the /feed route simply returns a 404 - the fallback to routing to the main code. If I add a +page.svelte to the /src/routes/feed/ it finds that route okay.

I have considerable experience with Vue but I'm new to Svelte/Sveltekit. Can someone point me in the right direction to add a dynamically generated RSS feed to a adapter-static sveltekit site? Also why does it work post build using npm run preview?

Upvotes: 0

Views: 28

Answers (1)

brunnerh
brunnerh

Reputation: 185280

preview operates on an intermediate version of the build, it cannot emulate every possible deployment environment, the adapter is not applied, so it will not be fully representative.

+server routes like this, which are not not just utilities to be accessed from load functions, seem to need their own export const prerender = true to output anything.

Also note that without an actual server that returns responses dynamically, you cannot set headers (like that Content-Type), the output is just a fixed file after all. Not sure how important the media type will be for clients accessing the feed, but if it matters, you might want to give the route an extension; those usually are automatically mapped to suitable types or can be configured to return a specific media type.

Depending on the server you might even need an extension since an extensionless feed file might not be served (leading to a 404).

Upvotes: 0

Related Questions