Skip to content

Commit

Permalink
🐛 Fixed sitemaps with no content (#15571)
Browse files Browse the repository at this point in the history
closes: #14981

- Taxonomy-specific sitemaps were invalid xml when there was no data
- These invalid empty sitemaps were referenced in the index sitemap causing SEO tools to report errors
  • Loading branch information
jbenezech authored and sam-lord committed Oct 17, 2022
1 parent 31d5448 commit 2d79d4c
Show file tree
Hide file tree
Showing 5 changed files with 24 additions and 5 deletions.
2 changes: 1 addition & 1 deletion ghost/core/core/frontend/services/sitemap/handler.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ module.exports = function handler(siteApp) {
const content = manager.getSiteMapXml(type, page);
// Prevent x-1.xml as it is a duplicate of x.xml and empty sitemaps
// (except for the first page so that at least one sitemap exists per type)
if (pageParam === '1' || (!content && page !== 1)) {
if (pageParam === '1' || content === null) {
return res.sendStatus(404);
}

Expand Down
4 changes: 1 addition & 3 deletions ghost/core/core/frontend/services/sitemap/index-generator.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,8 @@ class SiteMapIndexGenerator {

generateSiteMapUrlElements() {
return _.map(this.types, (resourceType) => {
// `|| 1` = even if there are no items we still have an empty sitemap file
const noOfPages = Math.ceil(Object.keys(resourceType.nodeLookup).length / this.maxPerPage) || 1;
const noOfPages = Math.ceil(Object.keys(resourceType.nodeLookup).length / this.maxPerPage);
const pages = [];

for (let i = 0; i < noOfPages; i++) {
const page = i === 0 ? '' : `-${i + 1}`;
const url = urlUtils.urlFor({relativeUrl: '/sitemap-' + resourceType.name + page + '.xml'}, true);
Expand Down
6 changes: 6 additions & 0 deletions ghost/core/test/e2e-frontend/custom_routes.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,4 +73,10 @@ describe('Custom Frontend routing', function () {
.expect(200)
.expect(assertCorrectFrontendHeaders);
});

it('should not serve empty sitemaps', async function () {
await request.get('/sitemap-authors.xml')
.expect(404)
.expect(assertCorrectFrontendHeaders);
});
});
16 changes: 16 additions & 0 deletions ghost/core/test/unit/frontend/services/sitemap/generator.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,11 @@ describe('Generators', function () {

describe('fn: getXml', function () {
it('default', function () {
generator.types.posts.addUrl('http://my-ghost-blog.com/episode-1/', {id: 'identifier1', staticRoute: true});
generator.types.pages.addUrl('http://my-ghost-blog.com/home/', {id: 'identifier1', staticRoute: true});
generator.types.tags.addUrl('http://my-ghost-blog.com/home/', {id: 'identifier1', staticRoute: true});
generator.types.authors.addUrl('http://my-ghost-blog.com/home/', {id: 'identifier1', staticRoute: true});

const xml = generator.getXml();

xml.should.match(/sitemap-tags.xml/);
Expand All @@ -101,6 +106,17 @@ describe('Generators', function () {
xml.should.match(/sitemap-authors.xml/);
});

it('does not create entries for pages with no content', function () {
generator.types.tags.addUrl('http://my-ghost-blog.com/episode-1/', {id: 'identifier1', staticRoute: true});

const xml = generator.getXml();

xml.should.match(/sitemap-tags.xml/);
xml.should.not.match(/sitemap-posts.xml/);
xml.should.not.match(/sitemap-pages.xml/);
xml.should.not.match(/sitemap-authors.xml/);
});

it('creates multiple pages when there are too many posts', function () {
for (let i = 0; i < 10; i++) {
generator.types.posts.addUrl(`http://my-ghost-blog.com/episode-${i}/`, testUtils.DataGenerator.forKnex.createPost({
Expand Down
1 change: 0 additions & 1 deletion ghost/core/test/utils/fixtures/settings/newroutes.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,3 @@ collections:

taxonomies:
tag: /category/{slug}/
author: /author/{slug}/

0 comments on commit 2d79d4c

Please sign in to comment.