Skip to content

Commit 14bec09

Browse files
OzakIOneslorber
andauthoredMar 14, 2024··
fix(blog): apply trailing slash to blog feed (#9920)
Co-authored-by: sebastien <lorber.sebastien@gmail.com>
1 parent 032e3b8 commit 14bec09

File tree

3 files changed

+419
-15
lines changed

3 files changed

+419
-15
lines changed
 

‎packages/docusaurus-plugin-content-blog/src/__tests__/__snapshots__/feed.test.ts.snap

+344
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,134 @@ exports[`atom has feed item for each post 1`] = `
220220
]
221221
`;
222222
223+
exports[`atom has feed item for each post - with trailing slash 1`] = `
224+
[
225+
"<?xml version="1.0" encoding="utf-8"?>
226+
<feed xmlns="http://www.w3.org/2005/Atom">
227+
<id>https://docusaurus.io/myBaseUrl/blog/</id>
228+
<title>Hello Blog</title>
229+
<updated>2023-07-23T00:00:00.000Z</updated>
230+
<generator>https://github.com/jpmonette/feed</generator>
231+
<link rel="alternate" href="https://docusaurus.io/myBaseUrl/blog/"/>
232+
<subtitle>Hello Blog</subtitle>
233+
<icon>https://docusaurus.io/myBaseUrl/image/favicon.ico</icon>
234+
<rights>Copyright</rights>
235+
<entry>
236+
<title type="html"><![CDATA[test links]]></title>
237+
<id>https://docusaurus.io/myBaseUrl/blog/blog-with-links/</id>
238+
<link href="https://docusaurus.io/myBaseUrl/blog/blog-with-links/"/>
239+
<updated>2023-07-23T00:00:00.000Z</updated>
240+
<summary type="html"><![CDATA[absolute full url]]></summary>
241+
<content type="html"><![CDATA[<p><a href="https://github.com/facebook/docusaurus" target="_blank" rel="noopener noreferrer">absolute full url</a></p>
242+
<p><a href="https://docusaurus.io/blog/heading-as-title">absolute pathname</a></p>
243+
<p><a href="https://docusaurus.io/blog/heading-as-title">relative pathname</a></p>
244+
<p><a href="https://docusaurus.io/blog/heading-as-title">md link</a></p>
245+
<p><a href="https://docusaurus.io/myBaseUrl/blog/blog-with-links/#title">anchor</a></p>
246+
<p><a href="https://docusaurus.io/blog/heading-as-title#title">relative pathname + anchor</a></p>
247+
<p><img loading="lazy" src="https://docusaurus.io/assets/images/test-image-742d39e51f41482e8132e79c09ad4eea.png" width="760" height="160" class="img_yGFe"></p>
248+
<p><img loading="lazy" src="https://docusaurus.io/assets/images/slash-introducing-411a16dd05086935b8e9ddae38ae9b45.svg" alt="" class="img_yGFe"></p>
249+
<img srcset="https://docusaurus.io/img/test-image.png 300w, https://docusaurus.io/img/docusaurus-social-card.png 500w">
250+
<img src="https://docusaurus.io/img/test-image.png">]]></content>
251+
</entry>
252+
<entry>
253+
<title type="html"><![CDATA[MDX Blog Sample with require calls]]></title>
254+
<id>https://docusaurus.io/myBaseUrl/blog/mdx-require-blog-post/</id>
255+
<link href="https://docusaurus.io/myBaseUrl/blog/mdx-require-blog-post/"/>
256+
<updated>2021-03-06T00:00:00.000Z</updated>
257+
<summary type="html"><![CDATA[Test MDX with require calls]]></summary>
258+
<content type="html"><![CDATA[<p>Test MDX with require calls</p>
259+
<!-- -->
260+
<!-- -->
261+
<img src="https://docusaurus.io/img/test-image.png">
262+
<img src="https://docusaurus.io/assets/images/test-image-742d39e51f41482e8132e79c09ad4eea.png">
263+
<img src="https://docusaurus.io/assets/images/test-image-742d39e51f41482e8132e79c09ad4eea.png">]]></content>
264+
</entry>
265+
<entry>
266+
<title type="html"><![CDATA[Full Blog Sample]]></title>
267+
<id>https://docusaurus.io/myBaseUrl/blog/mdx-blog-post/</id>
268+
<link href="https://docusaurus.io/myBaseUrl/blog/mdx-blog-post/"/>
269+
<updated>2021-03-05T00:00:00.000Z</updated>
270+
<summary type="html"><![CDATA[HTML Heading 1]]></summary>
271+
<content type="html"><![CDATA[<h1>HTML Heading 1</h1>
272+
<h2>HTML Heading 2</h2>
273+
<p>HTML Paragraph</p>
274+
<!-- -->
275+
<!-- -->
276+
<p>Import DOM</p>
277+
<h1>Heading 1</h1>
278+
<h2 class="anchor anchorWithHideOnScrollNavbar_G5V2" id="heading-2">Heading 2<a href="https://docusaurus.io/myBaseUrl/blog/mdx-blog-post/#heading-2" class="hash-link" aria-label="Direct link to Heading 2" title="Direct link to Heading 2">​</a></h2>
279+
<h3 class="anchor anchorWithHideOnScrollNavbar_G5V2" id="heading-3">Heading 3<a href="https://docusaurus.io/myBaseUrl/blog/mdx-blog-post/#heading-3" class="hash-link" aria-label="Direct link to Heading 3" title="Direct link to Heading 3">​</a></h3>
280+
<h4 class="anchor anchorWithHideOnScrollNavbar_G5V2" id="heading-4">Heading 4<a href="https://docusaurus.io/myBaseUrl/blog/mdx-blog-post/#heading-4" class="hash-link" aria-label="Direct link to Heading 4" title="Direct link to Heading 4">​</a></h4>
281+
<h5 class="anchor anchorWithHideOnScrollNavbar_G5V2" id="heading-5">Heading 5<a href="https://docusaurus.io/myBaseUrl/blog/mdx-blog-post/#heading-5" class="hash-link" aria-label="Direct link to Heading 5" title="Direct link to Heading 5">​</a></h5>
282+
<ul>
283+
<li>list1</li>
284+
<li>list2</li>
285+
<li>list3</li>
286+
</ul>
287+
<ul>
288+
<li>list1</li>
289+
<li>list2</li>
290+
<li>list3</li>
291+
</ul>
292+
<p>Normal Text <em>Italics Text</em> <strong>Bold Text</strong></p>
293+
<p><a href="https://v2.docusaurus.io/" target="_blank" rel="noopener noreferrer">link</a> <img loading="lazy" src="https://v2.docusaurus.io/" alt="image" class="img_yGFe"></p>]]></content>
294+
</entry>
295+
<entry>
296+
<title type="html"><![CDATA[Complex Slug]]></title>
297+
<id>https://docusaurus.io/myBaseUrl/blog/hey/my super path/héllô/</id>
298+
<link href="https://docusaurus.io/myBaseUrl/blog/hey/my super path/héllô/"/>
299+
<updated>2020-08-16T00:00:00.000Z</updated>
300+
<summary type="html"><![CDATA[complex url slug]]></summary>
301+
<content type="html"><![CDATA[<p>complex url slug</p>]]></content>
302+
<category label="date" term="date"/>
303+
<category label="complex" term="complex"/>
304+
</entry>
305+
<entry>
306+
<title type="html"><![CDATA[Simple Slug]]></title>
307+
<id>https://docusaurus.io/myBaseUrl/blog/simple/slug/</id>
308+
<link href="https://docusaurus.io/myBaseUrl/blog/simple/slug/"/>
309+
<updated>2020-08-15T00:00:00.000Z</updated>
310+
<summary type="html"><![CDATA[simple url slug]]></summary>
311+
<content type="html"><![CDATA[<p>simple url slug</p>]]></content>
312+
<author>
313+
<name>Sébastien Lorber</name>
314+
<uri>https://sebastienlorber.com</uri>
315+
</author>
316+
</entry>
317+
<entry>
318+
<title type="html"><![CDATA[some heading]]></title>
319+
<id>https://docusaurus.io/myBaseUrl/blog/heading-as-title/</id>
320+
<link href="https://docusaurus.io/myBaseUrl/blog/heading-as-title/"/>
321+
<updated>2019-01-02T00:00:00.000Z</updated>
322+
</entry>
323+
<entry>
324+
<title type="html"><![CDATA[date-matter]]></title>
325+
<id>https://docusaurus.io/myBaseUrl/blog/date-matter/</id>
326+
<link href="https://docusaurus.io/myBaseUrl/blog/date-matter/"/>
327+
<updated>2019-01-01T00:00:00.000Z</updated>
328+
<summary type="html"><![CDATA[date inside front matter]]></summary>
329+
<content type="html"><![CDATA[<p>date inside front matter</p>]]></content>
330+
<category label="date" term="date"/>
331+
</entry>
332+
<entry>
333+
<title type="html"><![CDATA[Happy 1st Birthday Slash! (translated)]]></title>
334+
<id>https://docusaurus.io/myBaseUrl/blog/2018/12/14/Happy-First-Birthday-Slash/</id>
335+
<link href="https://docusaurus.io/myBaseUrl/blog/2018/12/14/Happy-First-Birthday-Slash/"/>
336+
<updated>2018-12-14T00:00:00.000Z</updated>
337+
<summary type="html"><![CDATA[Happy birthday! (translated)]]></summary>
338+
<content type="html"><![CDATA[<p>Happy birthday! (translated)</p>]]></content>
339+
<author>
340+
<name>Yangshun Tay (translated)</name>
341+
</author>
342+
<author>
343+
<name>Sébastien Lorber (translated)</name>
344+
<email>lorber.sebastien@gmail.com</email>
345+
</author>
346+
</entry>
347+
</feed>",
348+
]
349+
`;
350+
223351
exports[`json filters to the first two entries 1`] = `
224352
[
225353
"{
@@ -378,6 +506,102 @@ exports[`json has feed item for each post 1`] = `
378506
]
379507
`;
380508
509+
exports[`json has feed item for each post - with trailing slash 1`] = `
510+
[
511+
"{
512+
"version": "https://jsonfeed.org/version/1",
513+
"title": "Hello Blog",
514+
"home_page_url": "https://docusaurus.io/myBaseUrl/blog/",
515+
"description": "Hello Blog",
516+
"items": [
517+
{
518+
"id": "https://docusaurus.io/myBaseUrl/blog/blog-with-links/",
519+
"content_html": "<p><a href=\\"https://github.com/facebook/docusaurus\\" target=\\"_blank\\" rel=\\"noopener noreferrer\\">absolute full url</a></p>/n<p><a href=\\"https://docusaurus.io/blog/heading-as-title\\">absolute pathname</a></p>/n<p><a href=\\"https://docusaurus.io/blog/heading-as-title\\">relative pathname</a></p>/n<p><a href=\\"https://docusaurus.io/blog/heading-as-title\\">md link</a></p>/n<p><a href=\\"https://docusaurus.io/myBaseUrl/blog/blog-with-links/#title\\">anchor</a></p>/n<p><a href=\\"https://docusaurus.io/blog/heading-as-title#title\\">relative pathname + anchor</a></p>/n<p><img loading=\\"lazy\\" src=\\"https://docusaurus.io/assets/images/test-image-742d39e51f41482e8132e79c09ad4eea.png\\" width=\\"760\\" height=\\"160\\" class=\\"img_yGFe\\"></p>/n<p><img loading=\\"lazy\\" src=\\"https://docusaurus.io/assets/images/slash-introducing-411a16dd05086935b8e9ddae38ae9b45.svg\\" alt=\\"\\" class=\\"img_yGFe\\"></p>/n<img srcset=\\"https://docusaurus.io/img/test-image.png 300w, https://docusaurus.io/img/docusaurus-social-card.png 500w\\">/n<img src=\\"https://docusaurus.io/img/test-image.png\\">",
520+
"url": "https://docusaurus.io/myBaseUrl/blog/blog-with-links/",
521+
"title": "test links",
522+
"summary": "absolute full url",
523+
"date_modified": "2023-07-23T00:00:00.000Z",
524+
"tags": []
525+
},
526+
{
527+
"id": "https://docusaurus.io/myBaseUrl/blog/mdx-require-blog-post/",
528+
"content_html": "<p>Test MDX with require calls</p>/n<!-- -->/n<!-- -->/n<img src=\\"https://docusaurus.io/img/test-image.png\\">/n<img src=\\"https://docusaurus.io/assets/images/test-image-742d39e51f41482e8132e79c09ad4eea.png\\">/n<img src=\\"https://docusaurus.io/assets/images/test-image-742d39e51f41482e8132e79c09ad4eea.png\\">",
529+
"url": "https://docusaurus.io/myBaseUrl/blog/mdx-require-blog-post/",
530+
"title": "MDX Blog Sample with require calls",
531+
"summary": "Test MDX with require calls",
532+
"date_modified": "2021-03-06T00:00:00.000Z",
533+
"tags": []
534+
},
535+
{
536+
"id": "https://docusaurus.io/myBaseUrl/blog/mdx-blog-post/",
537+
"content_html": "<h1>HTML Heading 1</h1>/n<h2>HTML Heading 2</h2>/n<p>HTML Paragraph</p>/n<!-- -->/n<!-- -->/n<p>Import DOM</p>/n<h1>Heading 1</h1>/n<h2 class=\\"anchor anchorWithHideOnScrollNavbar_G5V2\\" id=\\"heading-2\\">Heading 2<a href=\\"https://docusaurus.io/myBaseUrl/blog/mdx-blog-post/#heading-2\\" class=\\"hash-link\\" aria-label=\\"Direct link to Heading 2\\" title=\\"Direct link to Heading 2\\">​</a></h2>/n<h3 class=\\"anchor anchorWithHideOnScrollNavbar_G5V2\\" id=\\"heading-3\\">Heading 3<a href=\\"https://docusaurus.io/myBaseUrl/blog/mdx-blog-post/#heading-3\\" class=\\"hash-link\\" aria-label=\\"Direct link to Heading 3\\" title=\\"Direct link to Heading 3\\">​</a></h3>/n<h4 class=\\"anchor anchorWithHideOnScrollNavbar_G5V2\\" id=\\"heading-4\\">Heading 4<a href=\\"https://docusaurus.io/myBaseUrl/blog/mdx-blog-post/#heading-4\\" class=\\"hash-link\\" aria-label=\\"Direct link to Heading 4\\" title=\\"Direct link to Heading 4\\">​</a></h4>/n<h5 class=\\"anchor anchorWithHideOnScrollNavbar_G5V2\\" id=\\"heading-5\\">Heading 5<a href=\\"https://docusaurus.io/myBaseUrl/blog/mdx-blog-post/#heading-5\\" class=\\"hash-link\\" aria-label=\\"Direct link to Heading 5\\" title=\\"Direct link to Heading 5\\">​</a></h5>/n<ul>/n<li>list1</li>/n<li>list2</li>/n<li>list3</li>/n</ul>/n<ul>/n<li>list1</li>/n<li>list2</li>/n<li>list3</li>/n</ul>/n<p>Normal Text <em>Italics Text</em> <strong>Bold Text</strong></p>/n<p><a href=\\"https://v2.docusaurus.io/\\" target=\\"_blank\\" rel=\\"noopener noreferrer\\">link</a> <img loading=\\"lazy\\" src=\\"https://v2.docusaurus.io/\\" alt=\\"image\\" class=\\"img_yGFe\\"></p>",
538+
"url": "https://docusaurus.io/myBaseUrl/blog/mdx-blog-post/",
539+
"title": "Full Blog Sample",
540+
"summary": "HTML Heading 1",
541+
"date_modified": "2021-03-05T00:00:00.000Z",
542+
"tags": []
543+
},
544+
{
545+
"id": "https://docusaurus.io/myBaseUrl/blog/hey/my super path/héllô/",
546+
"content_html": "<p>complex url slug</p>",
547+
"url": "https://docusaurus.io/myBaseUrl/blog/hey/my super path/héllô/",
548+
"title": "Complex Slug",
549+
"summary": "complex url slug",
550+
"date_modified": "2020-08-16T00:00:00.000Z",
551+
"tags": [
552+
"date",
553+
"complex"
554+
]
555+
},
556+
{
557+
"id": "https://docusaurus.io/myBaseUrl/blog/simple/slug/",
558+
"content_html": "<p>simple url slug</p>",
559+
"url": "https://docusaurus.io/myBaseUrl/blog/simple/slug/",
560+
"title": "Simple Slug",
561+
"summary": "simple url slug",
562+
"date_modified": "2020-08-15T00:00:00.000Z",
563+
"author": {
564+
"name": "Sébastien Lorber",
565+
"url": "https://sebastienlorber.com"
566+
},
567+
"tags": []
568+
},
569+
{
570+
"id": "https://docusaurus.io/myBaseUrl/blog/heading-as-title/",
571+
"content_html": "",
572+
"url": "https://docusaurus.io/myBaseUrl/blog/heading-as-title/",
573+
"title": "some heading",
574+
"date_modified": "2019-01-02T00:00:00.000Z",
575+
"tags": []
576+
},
577+
{
578+
"id": "https://docusaurus.io/myBaseUrl/blog/date-matter/",
579+
"content_html": "<p>date inside front matter</p>",
580+
"url": "https://docusaurus.io/myBaseUrl/blog/date-matter/",
581+
"title": "date-matter",
582+
"summary": "date inside front matter",
583+
"date_modified": "2019-01-01T00:00:00.000Z",
584+
"tags": [
585+
"date"
586+
]
587+
},
588+
{
589+
"id": "https://docusaurus.io/myBaseUrl/blog/2018/12/14/Happy-First-Birthday-Slash/",
590+
"content_html": "<p>Happy birthday! (translated)</p>",
591+
"url": "https://docusaurus.io/myBaseUrl/blog/2018/12/14/Happy-First-Birthday-Slash/",
592+
"title": "Happy 1st Birthday Slash! (translated)",
593+
"summary": "Happy birthday! (translated)",
594+
"date_modified": "2018-12-14T00:00:00.000Z",
595+
"author": {
596+
"name": "Yangshun Tay (translated)"
597+
},
598+
"tags": []
599+
}
600+
]
601+
}",
602+
]
603+
`;
604+
381605
exports[`rss filters to the first two entries 1`] = `
382606
[
383607
"<?xml version="1.0" encoding="utf-8"?>
@@ -593,3 +817,123 @@ exports[`rss has feed item for each post 1`] = `
593817
</rss>",
594818
]
595819
`;
820+
821+
exports[`rss has feed item for each post - with trailing slash 1`] = `
822+
[
823+
"<?xml version="1.0" encoding="utf-8"?>
824+
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/">
825+
<channel>
826+
<title>Hello Blog</title>
827+
<link>https://docusaurus.io/myBaseUrl/blog/</link>
828+
<description>Hello Blog</description>
829+
<lastBuildDate>Sun, 23 Jul 2023 00:00:00 GMT</lastBuildDate>
830+
<docs>https://validator.w3.org/feed/docs/rss2.html</docs>
831+
<generator>https://github.com/jpmonette/feed</generator>
832+
<language>en</language>
833+
<copyright>Copyright</copyright>
834+
<item>
835+
<title><![CDATA[test links]]></title>
836+
<link>https://docusaurus.io/myBaseUrl/blog/blog-with-links/</link>
837+
<guid>https://docusaurus.io/myBaseUrl/blog/blog-with-links/</guid>
838+
<pubDate>Sun, 23 Jul 2023 00:00:00 GMT</pubDate>
839+
<description><![CDATA[absolute full url]]></description>
840+
<content:encoded><![CDATA[<p><a href="https://github.com/facebook/docusaurus" target="_blank" rel="noopener noreferrer">absolute full url</a></p>
841+
<p><a href="https://docusaurus.io/blog/heading-as-title">absolute pathname</a></p>
842+
<p><a href="https://docusaurus.io/blog/heading-as-title">relative pathname</a></p>
843+
<p><a href="https://docusaurus.io/blog/heading-as-title">md link</a></p>
844+
<p><a href="https://docusaurus.io/myBaseUrl/blog/blog-with-links/#title">anchor</a></p>
845+
<p><a href="https://docusaurus.io/blog/heading-as-title#title">relative pathname + anchor</a></p>
846+
<p><img loading="lazy" src="https://docusaurus.io/assets/images/test-image-742d39e51f41482e8132e79c09ad4eea.png" width="760" height="160" class="img_yGFe"></p>
847+
<p><img loading="lazy" src="https://docusaurus.io/assets/images/slash-introducing-411a16dd05086935b8e9ddae38ae9b45.svg" alt="" class="img_yGFe"></p>
848+
<img srcset="https://docusaurus.io/img/test-image.png 300w, https://docusaurus.io/img/docusaurus-social-card.png 500w">
849+
<img src="https://docusaurus.io/img/test-image.png">]]></content:encoded>
850+
</item>
851+
<item>
852+
<title><![CDATA[MDX Blog Sample with require calls]]></title>
853+
<link>https://docusaurus.io/myBaseUrl/blog/mdx-require-blog-post/</link>
854+
<guid>https://docusaurus.io/myBaseUrl/blog/mdx-require-blog-post/</guid>
855+
<pubDate>Sat, 06 Mar 2021 00:00:00 GMT</pubDate>
856+
<description><![CDATA[Test MDX with require calls]]></description>
857+
<content:encoded><![CDATA[<p>Test MDX with require calls</p>
858+
<!-- -->
859+
<!-- -->
860+
<img src="https://docusaurus.io/img/test-image.png">
861+
<img src="https://docusaurus.io/assets/images/test-image-742d39e51f41482e8132e79c09ad4eea.png">
862+
<img src="https://docusaurus.io/assets/images/test-image-742d39e51f41482e8132e79c09ad4eea.png">]]></content:encoded>
863+
</item>
864+
<item>
865+
<title><![CDATA[Full Blog Sample]]></title>
866+
<link>https://docusaurus.io/myBaseUrl/blog/mdx-blog-post/</link>
867+
<guid>https://docusaurus.io/myBaseUrl/blog/mdx-blog-post/</guid>
868+
<pubDate>Fri, 05 Mar 2021 00:00:00 GMT</pubDate>
869+
<description><![CDATA[HTML Heading 1]]></description>
870+
<content:encoded><![CDATA[<h1>HTML Heading 1</h1>
871+
<h2>HTML Heading 2</h2>
872+
<p>HTML Paragraph</p>
873+
<!-- -->
874+
<!-- -->
875+
<p>Import DOM</p>
876+
<h1>Heading 1</h1>
877+
<h2 class="anchor anchorWithHideOnScrollNavbar_G5V2" id="heading-2">Heading 2<a href="https://docusaurus.io/myBaseUrl/blog/mdx-blog-post/#heading-2" class="hash-link" aria-label="Direct link to Heading 2" title="Direct link to Heading 2">​</a></h2>
878+
<h3 class="anchor anchorWithHideOnScrollNavbar_G5V2" id="heading-3">Heading 3<a href="https://docusaurus.io/myBaseUrl/blog/mdx-blog-post/#heading-3" class="hash-link" aria-label="Direct link to Heading 3" title="Direct link to Heading 3">​</a></h3>
879+
<h4 class="anchor anchorWithHideOnScrollNavbar_G5V2" id="heading-4">Heading 4<a href="https://docusaurus.io/myBaseUrl/blog/mdx-blog-post/#heading-4" class="hash-link" aria-label="Direct link to Heading 4" title="Direct link to Heading 4">​</a></h4>
880+
<h5 class="anchor anchorWithHideOnScrollNavbar_G5V2" id="heading-5">Heading 5<a href="https://docusaurus.io/myBaseUrl/blog/mdx-blog-post/#heading-5" class="hash-link" aria-label="Direct link to Heading 5" title="Direct link to Heading 5">​</a></h5>
881+
<ul>
882+
<li>list1</li>
883+
<li>list2</li>
884+
<li>list3</li>
885+
</ul>
886+
<ul>
887+
<li>list1</li>
888+
<li>list2</li>
889+
<li>list3</li>
890+
</ul>
891+
<p>Normal Text <em>Italics Text</em> <strong>Bold Text</strong></p>
892+
<p><a href="https://v2.docusaurus.io/" target="_blank" rel="noopener noreferrer">link</a> <img loading="lazy" src="https://v2.docusaurus.io/" alt="image" class="img_yGFe"></p>]]></content:encoded>
893+
</item>
894+
<item>
895+
<title><![CDATA[Complex Slug]]></title>
896+
<link>https://docusaurus.io/myBaseUrl/blog/hey/my super path/héllô/</link>
897+
<guid>https://docusaurus.io/myBaseUrl/blog/hey/my super path/héllô/</guid>
898+
<pubDate>Sun, 16 Aug 2020 00:00:00 GMT</pubDate>
899+
<description><![CDATA[complex url slug]]></description>
900+
<content:encoded><![CDATA[<p>complex url slug</p>]]></content:encoded>
901+
<category>date</category>
902+
<category>complex</category>
903+
</item>
904+
<item>
905+
<title><![CDATA[Simple Slug]]></title>
906+
<link>https://docusaurus.io/myBaseUrl/blog/simple/slug/</link>
907+
<guid>https://docusaurus.io/myBaseUrl/blog/simple/slug/</guid>
908+
<pubDate>Sat, 15 Aug 2020 00:00:00 GMT</pubDate>
909+
<description><![CDATA[simple url slug]]></description>
910+
<content:encoded><![CDATA[<p>simple url slug</p>]]></content:encoded>
911+
</item>
912+
<item>
913+
<title><![CDATA[some heading]]></title>
914+
<link>https://docusaurus.io/myBaseUrl/blog/heading-as-title/</link>
915+
<guid>https://docusaurus.io/myBaseUrl/blog/heading-as-title/</guid>
916+
<pubDate>Wed, 02 Jan 2019 00:00:00 GMT</pubDate>
917+
</item>
918+
<item>
919+
<title><![CDATA[date-matter]]></title>
920+
<link>https://docusaurus.io/myBaseUrl/blog/date-matter/</link>
921+
<guid>https://docusaurus.io/myBaseUrl/blog/date-matter/</guid>
922+
<pubDate>Tue, 01 Jan 2019 00:00:00 GMT</pubDate>
923+
<description><![CDATA[date inside front matter]]></description>
924+
<content:encoded><![CDATA[<p>date inside front matter</p>]]></content:encoded>
925+
<category>date</category>
926+
</item>
927+
<item>
928+
<title><![CDATA[Happy 1st Birthday Slash! (translated)]]></title>
929+
<link>https://docusaurus.io/myBaseUrl/blog/2018/12/14/Happy-First-Birthday-Slash/</link>
930+
<guid>https://docusaurus.io/myBaseUrl/blog/2018/12/14/Happy-First-Birthday-Slash/</guid>
931+
<pubDate>Fri, 14 Dec 2018 00:00:00 GMT</pubDate>
932+
<description><![CDATA[Happy birthday! (translated)]]></description>
933+
<content:encoded><![CDATA[<p>Happy birthday! (translated)</p>]]></content:encoded>
934+
<author>lorber.sebastien@gmail.com (Sébastien Lorber (translated))</author>
935+
</item>
936+
</channel>
937+
</rss>",
938+
]
939+
`;

‎packages/docusaurus-plugin-content-blog/src/__tests__/feed.test.ts

+53-8
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import {jest} from '@jest/globals';
99
import path from 'path';
1010
import fs from 'fs-extra';
1111
import {DEFAULT_PARSE_FRONT_MATTER} from '@docusaurus/utils';
12+
import {fromPartial} from '@total-typescript/shoehorn';
1213
import {DEFAULT_OPTIONS} from '../options';
1314
import {generateBlogPosts} from '../blogUtils';
1415
import {createBlogFeedFiles} from '../feed';
@@ -80,12 +81,12 @@ describe.each(['atom', 'rss', 'json'])('%s', (feedType) => {
8081
const outDir = path.join(siteDir, 'build-snap');
8182

8283
await testGenerateFeeds(
83-
{
84+
fromPartial({
8485
siteDir,
8586
siteConfig,
8687
i18n: DefaultI18N,
8788
outDir,
88-
} as LoadContext,
89+
}),
8990
{
9091
path: 'invalid-blog-path',
9192
routeBasePath: 'blog',
@@ -120,12 +121,12 @@ describe.each(['atom', 'rss', 'json'])('%s', (feedType) => {
120121
// Build is quite difficult to mock, so we built the blog beforehand and
121122
// copied the output to the fixture...
122123
await testGenerateFeeds(
123-
{
124+
fromPartial({
124125
siteDir,
125126
siteConfig,
126127
i18n: DefaultI18N,
127128
outDir,
128-
} as LoadContext,
129+
}),
129130
{
130131
path: 'blog',
131132
routeBasePath: 'blog',
@@ -163,12 +164,12 @@ describe.each(['atom', 'rss', 'json'])('%s', (feedType) => {
163164
// Build is quite difficult to mock, so we built the blog beforehand and
164165
// copied the output to the fixture...
165166
await testGenerateFeeds(
166-
{
167+
fromPartial({
167168
siteDir,
168169
siteConfig,
169170
i18n: DefaultI18N,
170171
outDir,
171-
} as LoadContext,
172+
}),
172173
{
173174
path: 'blog',
174175
routeBasePath: 'blog',
@@ -216,12 +217,12 @@ describe.each(['atom', 'rss', 'json'])('%s', (feedType) => {
216217
// Build is quite difficult to mock, so we built the blog beforehand and
217218
// copied the output to the fixture...
218219
await testGenerateFeeds(
219-
{
220+
fromPartial({
220221
siteDir,
221222
siteConfig,
222223
i18n: DefaultI18N,
223224
outDir,
224-
} as LoadContext,
225+
}),
225226
{
226227
path: 'blog',
227228
routeBasePath: 'blog',
@@ -245,4 +246,48 @@ describe.each(['atom', 'rss', 'json'])('%s', (feedType) => {
245246
).toMatchSnapshot();
246247
fsMock.mockClear();
247248
});
249+
250+
it('has feed item for each post - with trailing slash', async () => {
251+
const siteDir = path.join(__dirname, '__fixtures__', 'website');
252+
const outDir = path.join(siteDir, 'build-snap');
253+
const siteConfig = {
254+
title: 'Hello',
255+
baseUrl: '/myBaseUrl/',
256+
url: 'https://docusaurus.io',
257+
favicon: 'image/favicon.ico',
258+
trailingSlash: true,
259+
markdown,
260+
};
261+
262+
// Build is quite difficult to mock, so we built the blog beforehand and
263+
// copied the output to the fixture...
264+
await testGenerateFeeds(
265+
fromPartial({
266+
siteDir,
267+
siteConfig,
268+
i18n: DefaultI18N,
269+
outDir,
270+
}),
271+
{
272+
path: 'blog',
273+
routeBasePath: 'blog',
274+
tagsBasePath: 'tags',
275+
authorsMapPath: 'authors.yml',
276+
include: DEFAULT_OPTIONS.include,
277+
exclude: DEFAULT_OPTIONS.exclude,
278+
feedOptions: {
279+
type: [feedType],
280+
copyright: 'Copyright',
281+
},
282+
readingTime: ({content, defaultReadingTime}) =>
283+
defaultReadingTime({content}),
284+
truncateMarker: /<!--\s*truncate\s*-->/,
285+
} as PluginOptions,
286+
);
287+
288+
expect(
289+
fsMock.mock.calls.map((call) => call[1] as string),
290+
).toMatchSnapshot();
291+
fsMock.mockClear();
292+
});
248293
});

‎packages/docusaurus-plugin-content-blog/src/feed.ts

+22-7
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,10 @@ import logger from '@docusaurus/logger';
1111
import {Feed, type Author as FeedAuthor} from 'feed';
1212
import * as srcset from 'srcset';
1313
import {normalizeUrl, readOutputHTMLFile} from '@docusaurus/utils';
14-
import {blogPostContainerID} from '@docusaurus/utils-common';
14+
import {
15+
blogPostContainerID,
16+
applyTrailingSlash,
17+
} from '@docusaurus/utils-common';
1518
import {load as cheerioLoad} from 'cheerio';
1619
import type {DocusaurusConfig} from '@docusaurus/types';
1720
import type {
@@ -40,8 +43,14 @@ async function generateBlogFeed({
4043
}
4144

4245
const {feedOptions, routeBasePath} = options;
43-
const {url: siteUrl, baseUrl, title, favicon} = siteConfig;
44-
const blogBaseUrl = normalizeUrl([siteUrl, baseUrl, routeBasePath]);
46+
const {url: siteUrl, baseUrl, title, favicon, trailingSlash} = siteConfig;
47+
const blogBaseUrl = applyTrailingSlash(
48+
normalizeUrl([siteUrl, baseUrl, routeBasePath]),
49+
{
50+
trailingSlash,
51+
baseUrl,
52+
},
53+
);
4554

4655
const blogPostsForFeed =
4756
feedOptions.limit === false || feedOptions.limit === null
@@ -85,7 +94,7 @@ async function defaultCreateFeedItems({
8594
siteConfig: DocusaurusConfig;
8695
outDir: string;
8796
}): Promise<BlogFeedItem[]> {
88-
const {url: siteUrl} = siteConfig;
97+
const {url: siteUrl, baseUrl, trailingSlash} = siteConfig;
8998

9099
function toFeedAuthor(author: Author): FeedAuthor {
91100
return {name: author.name, link: author.url, email: author.email};
@@ -105,13 +114,19 @@ async function defaultCreateFeedItems({
105114
} = post;
106115

107116
const content = await readOutputHTMLFile(
108-
permalink.replace(siteConfig.baseUrl, ''),
117+
permalink.replace(baseUrl, ''),
109118
outDir,
110-
siteConfig.trailingSlash,
119+
trailingSlash,
111120
);
112121
const $ = cheerioLoad(content);
113122

114-
const blogPostAbsoluteUrl = normalizeUrl([siteUrl, permalink]);
123+
const blogPostAbsoluteUrl = applyTrailingSlash(
124+
normalizeUrl([siteUrl, permalink]),
125+
{
126+
trailingSlash,
127+
baseUrl,
128+
},
129+
);
115130

116131
const toAbsoluteUrl = (src: string) =>
117132
String(new URL(src, blogPostAbsoluteUrl));

0 commit comments

Comments
 (0)
Please sign in to comment.