Gatsby: 404 when trying to access rss.xml

Created on 24 Jul 2018  路  8Comments  路  Source: gatsbyjs/gatsby

Summary

I'm using the plugin gatsby-plugin-feed to generate a feed. When I try to access rss.xml (in production as it can be seen here http://templecoding.com/rss.xml it returns a 404, with this error in the console:

A page wasn't found for "/rss.xml"

But if I reload the page (Ctrl + R), the feed is then shown.

I can see a similar issue with google adsense, usually the ads are not visible on the page unless I reload the once I am on it.

What is it that I'm missing?

Relevant information

I'm using the latest v2

Environment (if relevant)

File contents (if changed)

gatsby-config.js:

const config = require("./config/SiteConfig");

const pathPrefix = config.pathPrefix === "/" ? "" : config.pathPrefix;

module.exports = {
    pathPrefix: config.pathPrefix,
    siteMetadata: {
        title: "Temple Coding",
        siteUrl: config.siteUrl + pathPrefix,
        buildTime: new Date(Date.now()).toLocaleString(),
        description: "The personal blog of Thiago Temple."
    },
    plugins: [
        "gatsby-plugin-feed",
        "gatsby-plugin-react-helmet",
        "gatsby-plugin-styled-components",
        {
            resolve: "gatsby-source-filesystem",
            options: {
                name: "post",
                path: `${__dirname}/blog`
            }
        },
        {
            resolve: "gatsby-transformer-remark",
            options: {
                plugins: [
                    {
                        resolve: "gatsby-remark-external-links",
                        options: {
                            target: "_blank",
                            rel: "nofollow noopener noreferrer"
                        }
                    },
                    "gatsby-remark-prismjs",
                    "gatsby-remark-autolink-headers",
                    {
                        resolve: `gatsby-remark-images`,
                        options: {
                            // It's important to specify the maxWidth (in pixels) of
                            // the content container as this plugin uses this as the
                            // base for generating different widths of each image.
                            maxWidth: 590
                        }
                    },
                    "gatsby-remark-copy-linked-files"
                ]
            }
        },
        {
            resolve: "gatsby-plugin-typography",
            options: {
                pathToConfigModule: "src/utils/typography.js"
            }
        },
        "gatsby-plugin-catch-links",
        "gatsby-plugin-sitemap",
        "gatsby-plugin-lodash",
        {
            resolve: "gatsby-plugin-manifest",
            options: {
                name: config.siteTitle,
                short_name: config.siteTitleAlt,
                description: config.siteDescription,
                start_url: config.pathPrefix,
                background_color: config.backgroundColor,
                theme_color: config.themeColor,
                display: "fullscreen",
                icon: "src/favicon.jpg"
            }
        },
        "gatsby-plugin-offline",
        {
            resolve: "gatsby-plugin-google-analytics",
            options: {
                trackingId: "UA-41090209-2",
                head: false,
                anonymize: true,
                respectDNT: true
            }
        }
    ]
};

package.json:

{
    "name": "templecoding-site",
    "description": "The personal blog of Thiago Temple.",
    "version": "1.0.0",
    "author": "Thiago Temple <[email protected]>",
    "dependencies": {
        "babel-plugin-styled-components": "^1.5.1",
        "disqus-react": "^1.0.5",
        "gatsby": "^2.0.0-beta.40",
        "gatsby-paginate": "^1.0.16",
        "gatsby-plugin-catch-links": "^2.0.2-beta.2",
        "gatsby-plugin-feed": "^1.3.25",
        "gatsby-plugin-google-analytics": "^1.0.31",
        "gatsby-plugin-lodash": "^3.0.1-beta.2",
        "gatsby-plugin-manifest": "^2.0.2-beta.2",
        "gatsby-plugin-offline": "^2.0.0-beta.3",
        "gatsby-plugin-react-helmet": "^3.0.0-beta.3",
        "gatsby-plugin-sharp": "^1.6.48",
        "gatsby-plugin-sitemap": "^2.0.0-beta.2",
        "gatsby-plugin-styled-components": "^3.0.0-beta.2",
        "gatsby-plugin-typography": "^2.2.0-beta.2",
        "gatsby-remark-autolink-headers": "^2.0.0-beta.3",
        "gatsby-remark-copy-linked-files": "^1.5.37",
        "gatsby-remark-external-links": "0.0.4",
        "gatsby-remark-images": "^1.5.67",
        "gatsby-remark-prismjs": "^3.0.0-beta.3",
        "gatsby-remark-responsive-image": "^1.0.0-alpha13-alpha.435e0178",
        "gatsby-source-filesystem": "^2.0.1-beta.5",
        "gatsby-transformer-remark": "^2.1.1-beta.3",
        "polished": "^1.9.2",
        "prismjs": "^1.14.0",
        "prop-types": "^15.6.1",
        "react": "^16.4.1",
        "react-dom": "^16.4.1",
        "react-helmet": "^5.2.0",
        "react-icons": "^2.2.7",
        "react-share": "^2.2.0",
        "react-typography": "^0.16.13",
        "styled-components": "^3.3.2",
        "typography": "^0.16.17"
    },
    "keywords": [
        "gatsby",
        "thiago temple",
        "temple coding",
        "blog"
    ],
    "license": "MIT",
    "main": "n/a",
    "scripts": {
        "build": "gatsby build",
        "serve": "gatsby serve",
        "dev": "gatsby develop -o"
    },
    "devDependencies": {
        "babel-eslint": "^8.2.2",
        "babel-preset-env": "^1.6.1",
        "eslint": "^4.18.2",
        "eslint-config-airbnb": "^16.1.0",
        "eslint-config-prettier": "^2.9.0",
        "eslint-plugin-import": "^2.9.0",
        "eslint-plugin-jsx-a11y": "^6.0.3",
        "eslint-plugin-prettier": "^2.6.0",
        "eslint-plugin-react": "^7.7.0",
        "prettier": "^1.11.1"
    },
    "browserslist": [
        "> 1%",
        "IE >= 9",
        "last 2 versions"
    ]
}

gatsby-node.js:

const path = require("path");
const _ = require("lodash");
const createPaginatedPages = require("gatsby-paginate");

exports.onCreateNode = ({ node, actions }) => {
    const { createNodeField } = actions;
    let slug;
    if (node.internal.type === "MarkdownRemark") {
        if (
            Object.prototype.hasOwnProperty.call(node, "frontmatter") &&
            Object.prototype.hasOwnProperty.call(node.frontmatter, "slug")
        ) {
            slug = `/${_.kebabCase(node.frontmatter.slug)}`;
        }
        if (
            Object.prototype.hasOwnProperty.call(node, "frontmatter") &&
            Object.prototype.hasOwnProperty.call(node.frontmatter, "title")
        ) {
            slug = `/${_.kebabCase(node.frontmatter.title)}`;
        }
        createNodeField({ node, name: "slug", value: slug });
    }
};

exports.createPages = ({ graphql, actions }) => {
    const { createPage } = actions;

    return new Promise((resolve, reject) => {
        const postPage = path.resolve("src/templates/post.js");
        const categoryPage = path.resolve("src/templates/category.js");
        resolve(
            graphql(`
                {
                    posts: allMarkdownRemark(
                        sort: { fields: [frontmatter___date], order: DESC }
                    ) {
                        edges {
                            node {
                                fields {
                                    slug
                                }
                                frontmatter {
                                    title
                                    date(formatString: "YYYY-MM-DD")
                                    category
                                    path
                                }
                                excerpt(pruneLength: 200)
                                timeToRead
                            }
                        }
                    }
                }
            `).then(result => {
                if (result.errors) {
                    console.log(result.errors);
                    reject(result.errors);
                }

                createPaginatedPages({
                    edges: result.data.posts.edges,
                    createPage: createPage,
                    pageTemplate: "src/templates/index.js",
                    pageLength: 5, // This is optional and defaults to 10 if not used
                    pathPrefix: "", // This is optional and defaults to an empty string if not used
                    context: {} // This is optional and defaults to an empty object if not used
                });

                const posts = result.data.posts.edges;

                posts.forEach((edge, index) => {
                    const next = index === 0 ? null : posts[index - 1].node;
                    const prev =
                        index === posts.length - 1
                            ? null
                            : posts[index + 1].node;

                    createPage({
                        path: edge.node.frontmatter.path,
                        component: postPage,
                        context: {
                            slug: edge.node.fields.slug,
                            prev,
                            next
                        }
                    });
                });

                let categories = [];

                _.each(posts, edge => {
                    if (_.get(edge, "node.frontmatter.category")) {
                        categories = categories.concat(
                            edge.node.frontmatter.category
                        );
                    }
                });

                categories = _.uniq(categories);

                categories.forEach(category => {
                    createPage({
                        path: `/categories/${_.kebabCase(category)}`,
                        component: categoryPage,
                        context: {
                            category
                        }
                    });
                });
            })
        );
    });
};

gatsby-browser.js: N/A
gatsby-ssr.js: N/A

question or discussion

Most helpful comment

I was using <Link to="/rss.xml">Feed</Link>

Aha! @thitemple Gatsby's Link component is designed to handle preloading links to pages within a Gatsby site. It seems that with the above code snippet, Link was trying to find an HTML page for rss.xml, failing to find it and so showing a 404 page instead. There's a little bit of info about that at https://www.gatsbyjs.org/packages/gatsby-link/#for-internal-links-only.

I wonder if Gatsby should output a warning when the Link component is used like this?

All 8 comments

Could it be a problem with your browser? I tested visiting your RSS.xml URL using 3 different browsers and they correctly fetched the XML the first time.

Also tested and loaded without issues on Chrome.

So, the issue was happening when I tried to click on the Feed link located at the page's footer. When I was writing this I decided to make a test I was using <Link to="/rss.xml">Feed</Link> and now I replaced it with an anchor tag. Now it's working. Do you have an idea why?
Thanks

I'm not entirely sure.
It could be the link you provided is http and the live site forwards to https. When you use the relative route it wouldn't have that issue. Also, sometimes people forget the https at the beginning of a link and only enter to="templecoding.com/rss.xml" which makes the path relative. Those are random guesses on common scenarios -- it's really hard to know for sure.

Closing the issue is it's resolved!

I was using <Link to="/rss.xml">Feed</Link>

Aha! @thitemple Gatsby's Link component is designed to handle preloading links to pages within a Gatsby site. It seems that with the above code snippet, Link was trying to find an HTML page for rss.xml, failing to find it and so showing a 404 page instead. There's a little bit of info about that at https://www.gatsbyjs.org/packages/gatsby-link/#for-internal-links-only.

I wonder if Gatsby should output a warning when the Link component is used like this?

If a warning is something possible @m-allanson, that would be of great help

Was this page helpful?
0 / 5 - 0 ratings

Related issues

KyleAMathews picture KyleAMathews  路  3Comments

kalinchernev picture kalinchernev  路  3Comments

ferMartz picture ferMartz  路  3Comments

timbrandin picture timbrandin  路  3Comments

totsteps picture totsteps  路  3Comments