aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/components/Layouts/Layout.tsx22
-rw-r--r--src/pages/atom.xml.tsx20
-rw-r--r--src/pages/feed.json.tsx20
-rw-r--r--src/pages/feed.xml.tsx20
-rw-r--r--src/utils/helpers/rss.ts61
5 files changed, 143 insertions, 0 deletions
diff --git a/src/components/Layouts/Layout.tsx b/src/components/Layouts/Layout.tsx
index 35e7d27..8a57cf6 100644
--- a/src/components/Layouts/Layout.tsx
+++ b/src/components/Layouts/Layout.tsx
@@ -4,6 +4,8 @@ import Header from '@components/Header/Header';
import Main from '@components/Main/Main';
import Breadcrumb from '@components/Breadcrumb/Breadcrumb';
import { t } from '@lingui/macro';
+import Head from 'next/head';
+import { config } from '@config/website';
const Layout = ({
children,
@@ -14,6 +16,26 @@ const Layout = ({
}) => {
return (
<>
+ <Head>
+ <link
+ rel="alternate"
+ href="/feed.xml"
+ type="application/rss+xml"
+ title={`${config.name}'s RSS feed`}
+ />
+ <link
+ rel="alternate"
+ href="/atom.xml"
+ type="application/atom+xml"
+ title={`${config.name}'s RSS feed`}
+ />
+ <link
+ rel="alternate"
+ href="/feed.json"
+ type="application/feed+json"
+ title={`${config.name}'s RSS feed`}
+ />
+ </Head>
<a href="#main" className="screen-reader-text">{t`Skip to content`}</a>
<Header isHome={isHome} />
<Main>{children}</Main>
diff --git a/src/pages/atom.xml.tsx b/src/pages/atom.xml.tsx
new file mode 100644
index 0000000..e6908bd
--- /dev/null
+++ b/src/pages/atom.xml.tsx
@@ -0,0 +1,20 @@
+import { generateFeed } from '@utils/helpers/rss';
+import { GetServerSideProps } from 'next';
+
+const Feed = () => null;
+
+export const getServerSideProps: GetServerSideProps = async ({ res }) => {
+ const feed = await generateFeed();
+
+ if (res) {
+ res.setHeader('Content-Type', 'text/xml');
+ res.write(`${feed.atom1()}`);
+ res.end();
+ }
+
+ return {
+ props: {},
+ };
+};
+
+export default Feed;
diff --git a/src/pages/feed.json.tsx b/src/pages/feed.json.tsx
new file mode 100644
index 0000000..e113b46
--- /dev/null
+++ b/src/pages/feed.json.tsx
@@ -0,0 +1,20 @@
+import { generateFeed } from '@utils/helpers/rss';
+import { GetServerSideProps } from 'next';
+
+const Feed = () => null;
+
+export const getServerSideProps: GetServerSideProps = async ({ res }) => {
+ const feed = await generateFeed();
+
+ if (res) {
+ res.setHeader('Content-Type', 'application/json');
+ res.write(`${feed.json1()}`);
+ res.end();
+ }
+
+ return {
+ props: {},
+ };
+};
+
+export default Feed;
diff --git a/src/pages/feed.xml.tsx b/src/pages/feed.xml.tsx
new file mode 100644
index 0000000..093cab8
--- /dev/null
+++ b/src/pages/feed.xml.tsx
@@ -0,0 +1,20 @@
+import { generateFeed } from '@utils/helpers/rss';
+import { GetServerSideProps } from 'next';
+
+const Feed = () => null;
+
+export const getServerSideProps: GetServerSideProps = async ({ res }) => {
+ const feed = await generateFeed();
+
+ if (res) {
+ res.setHeader('Content-Type', 'text/xml');
+ res.write(`${feed.rss2()}`);
+ res.end();
+ }
+
+ return {
+ props: {},
+ };
+};
+
+export default Feed;
diff --git a/src/utils/helpers/rss.ts b/src/utils/helpers/rss.ts
new file mode 100644
index 0000000..7851ff8
--- /dev/null
+++ b/src/utils/helpers/rss.ts
@@ -0,0 +1,61 @@
+import { config } from '@config/website';
+import { getPublishedPosts } from '@services/graphql/queries';
+import { ArticlePreview } from '@ts/types/articles';
+import { PostsList } from '@ts/types/blog';
+import { Feed } from 'feed';
+
+const getAllPosts = async (): Promise<ArticlePreview[]> => {
+ const posts: ArticlePreview[] = [];
+ let hasNextPage = true;
+ let after = undefined;
+
+ do {
+ const postsList: PostsList = await getPublishedPosts({ first: 10, after });
+ posts.push(...postsList.posts);
+ hasNextPage = postsList.pageInfo.hasNextPage;
+ after = postsList.pageInfo.endCursor;
+ } while (hasNextPage);
+
+ return posts;
+};
+
+export const generateFeed = async () => {
+ const websiteUrl = process.env.FRONTEND_URL ? process.env.FRONTEND_URL : '';
+ const author = {
+ name: config.name,
+ email: process.env.AUTHOR_EMAIL,
+ link: websiteUrl,
+ };
+ const copyright = `${config.name} CC BY SA ${config.copyright.startYear} - ${config.copyright.endYear}`;
+ const title = `${config.name} | ${config.baseline}`;
+
+ const feed = new Feed({
+ author,
+ copyright,
+ description: process.env.FEED_DESCRIPTION,
+ feedLinks: {
+ json: `${websiteUrl}/feed/json`,
+ atom: `${websiteUrl}/feed/atom`,
+ },
+ generator: 'Feed & NextJS',
+ id: websiteUrl,
+ language: config.defaultLocale,
+ link: websiteUrl,
+ title,
+ });
+
+ const posts = await getAllPosts();
+
+ posts.forEach((post) => {
+ feed.addItem({
+ content: post.intro,
+ date: new Date(post.dates.publication),
+ description: post.intro,
+ id: post.id,
+ link: `${websiteUrl}/article/${post.slug}`,
+ title: post.title,
+ });
+ });
+
+ return feed;
+};