Merge pull request #169 from life-itself/164-optimize-seo
[site/seo]: page speed optimization, keywords and sitemap for seo
This commit is contained in:
commit
f440456dd0
|
|
@ -3,7 +3,7 @@ title: Collective Action Problems & Climate Change
|
||||||
created: 2022-04-13
|
created: 2022-04-13
|
||||||
date: 2022-03-01
|
date: 2022-03-01
|
||||||
description: 'In this episode we use the example of KlimaDAO to explore the interaction between climate change and the public goods problem.'
|
description: 'In this episode we use the example of KlimaDAO to explore the interaction between climate change and the public goods problem.'
|
||||||
image: /img/Collective Action Climate.png
|
image: /img/Collective Action Climate.jpg
|
||||||
youtube: https://www.youtube.com/watch?v=SLXtnCL6IxE
|
youtube: https://www.youtube.com/watch?v=SLXtnCL6IxE
|
||||||
podcast: https://anchor.fm/life-itself/episodes/Collective-Action-Problems--Climate-Change-e1h4o6e/a-a7gpq18
|
podcast: https://anchor.fm/life-itself/episodes/Collective-Action-Problems--Climate-Change-e1h4o6e/a-a7gpq18
|
||||||
featured: true
|
featured: true
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ title: Web3 and Post-State Technocracy
|
||||||
created: 2022-03-21
|
created: 2022-03-21
|
||||||
date: 2022-02-17
|
date: 2022-02-17
|
||||||
description: "In this episode we explore the aspirational transition from the existing US-led international order to a world in which blockchain technology and technocracy are the new foundations for global human governance."
|
description: "In this episode we explore the aspirational transition from the existing US-led international order to a world in which blockchain technology and technocracy are the new foundations for global human governance."
|
||||||
image: /img/technocracy.jpg
|
image: /img/post-state-technocracy.jpg
|
||||||
youtube: https://www.youtube.com/watch?v=gZ0iCJkM3PU
|
youtube: https://www.youtube.com/watch?v=gZ0iCJkM3PU
|
||||||
podcast: https://anchor.fm/life-itself/episodes/On-Web3-and-Post-State-Technocracy-with-Stephen-Diehl--Rufus-Pollock-e1g4cpe
|
podcast: https://anchor.fm/life-itself/episodes/On-Web3-and-Post-State-Technocracy-with-Stephen-Diehl--Rufus-Pollock-e1g4cpe
|
||||||
featured: true
|
featured: true
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@
|
||||||
|
|
||||||
# production
|
# production
|
||||||
/build
|
/build
|
||||||
|
public/sitemap.xml
|
||||||
|
|
||||||
# misc
|
# misc
|
||||||
.DS_Store
|
.DS_Store
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
import { Tooltip } from './Tooltip';
|
import { Tooltip } from './Tooltip';
|
||||||
import siteConfig from '../config/siteConfig.js'
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Component for adding previews on hovering over anchor tags with relative paths
|
* Component for adding previews on hovering over anchor tags with relative paths
|
||||||
|
|
|
||||||
|
|
@ -14,11 +14,12 @@ export function Latest({ posts }) {
|
||||||
<div className="mt-12 max-w-lg mx-auto grid gap-5 lg:grid-cols-3 lg:max-w-none">
|
<div className="mt-12 max-w-lg mx-auto grid gap-5 lg:grid-cols-3 lg:max-w-none">
|
||||||
{posts && posts.map((post) => (
|
{posts && posts.map((post) => (
|
||||||
<div key={post.title} className="flex flex-col rounded-lg shadow-lg overflow-hidden">
|
<div key={post.title} className="flex flex-col rounded-lg shadow-lg overflow-hidden">
|
||||||
<div className="flex-shrink-0">
|
{post.image ?
|
||||||
{post.image ? <img className="h-48 w-full object-cover" src={post.image} alt={post.title} />
|
<div className="h-48 flex-shrink-0">
|
||||||
: <div className="h-20 w-full bg-slate-500" />
|
<img className="" width="100%" height="100%" src={post.image} alt={post.title} />
|
||||||
}
|
</div>
|
||||||
</div>
|
: <div className="h-20 w-full bg-slate-500" />
|
||||||
|
}
|
||||||
<div className="flex-1 bg-slate-800 p-6 flex flex-col justify-between">
|
<div className="flex-1 bg-slate-800 p-6 flex flex-col justify-between">
|
||||||
<div className="flex-1">
|
<div className="flex-1">
|
||||||
<p className="text-sm font-medium text-indigo-600 dark:text-yellow-500">
|
<p className="text-sm font-medium text-indigo-600 dark:text-yellow-500">
|
||||||
|
|
|
||||||
|
|
@ -12,8 +12,6 @@ export default function Layout({ children }) {
|
||||||
<meta name="viewport" content="initial-scale=1.0, width=device-width" />
|
<meta name="viewport" content="initial-scale=1.0, width=device-width" />
|
||||||
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossOrigin="" />
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossOrigin="" />
|
||||||
{/* <link href="https://fonts.googleapis.com/css2?family=Nunito+Sans&display=swap" rel="stylesheet" />
|
|
||||||
<link href="https://fonts.googleapis.com/css2?family=Inter&display=swap" rel="stylesheet"></link> */}
|
|
||||||
</Head>
|
</Head>
|
||||||
<Nav />
|
<Nav />
|
||||||
<main>
|
<main>
|
||||||
|
|
@ -45,7 +43,7 @@ export default function Layout({ children }) {
|
||||||
target="_blank"
|
target="_blank"
|
||||||
rel="noopener noreferrer"
|
rel="noopener noreferrer"
|
||||||
>
|
>
|
||||||
<img src={siteConfig.authorLogo} alt={siteConfig.author} className="mx-2 h-6 inline-block" />
|
<img src={siteConfig.authorLogo} alt={siteConfig.author} width="20" height="20" className="mx-2 h-6 inline-block" />
|
||||||
{siteConfig.author}
|
{siteConfig.author}
|
||||||
{' '}
|
{' '}
|
||||||
Licensed under a CC-By 4.0 International License
|
Licensed under a CC-By 4.0 International License
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,15 @@
|
||||||
import Head from 'next/head'
|
import Head from 'next/head'
|
||||||
import ReactPlayer from 'react-player/lazy'
|
import dynamic from 'next/dynamic'
|
||||||
import { NextSeo } from 'next-seo'
|
import { NextSeo } from 'next-seo'
|
||||||
import siteConfig from "../config/siteConfig"
|
import siteConfig from "../config/siteConfig"
|
||||||
import { Paragraph } from './Paragraph'
|
import LiteYouTubeEmbed from "react-lite-youtube-embed"
|
||||||
import { Anchor } from './Anchor'
|
import { YOUTUBE_REGEX } from "../lib/constants"
|
||||||
|
|
||||||
|
const Anchor = dynamic(() => import('./Anchor').then(module => module.Anchor), {
|
||||||
|
ssr: false
|
||||||
|
})
|
||||||
|
|
||||||
|
const Paragraph = dynamic(() => import("./Paragraph").then(mod => mod.Paragraph))
|
||||||
|
|
||||||
const components = {
|
const components = {
|
||||||
Head,
|
Head,
|
||||||
|
|
@ -11,30 +17,25 @@ const components = {
|
||||||
a: Anchor
|
a: Anchor
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function MdxPage({ children, editUrl }) {
|
export default function MdxPage({ children }) {
|
||||||
const { Component, frontmatter: {
|
const { Component, frontmatter: {
|
||||||
title, description, date, authors, youtube, podcast, image, _raw
|
title, description, date, keywords, youtube, podcast, image, _raw
|
||||||
}} = children
|
}} = children
|
||||||
|
|
||||||
let youtubeThumnbnail
|
let youtubeThumnbnail
|
||||||
let podcastEmbed
|
|
||||||
|
|
||||||
if (youtube && !image) {
|
const youtubeId =
|
||||||
|
youtube && YOUTUBE_REGEX.test(youtube) && youtube.split(/^|=|\//).pop();
|
||||||
|
|
||||||
|
if (youtubeId && !image) {
|
||||||
// get the youtube thumbnail image from https://img.youtube.com/vi/<youtube-video-id>/maxresdefault.jpg
|
// get the youtube thumbnail image from https://img.youtube.com/vi/<youtube-video-id>/maxresdefault.jpg
|
||||||
const regex =
|
youtubeThumnbnail = youtube.replace(
|
||||||
/\www.youtube.com\/\embed\/|youtube.com\/\embed\/|youtu.be\/|\www.youtube.com\/\watch\?v=|\youtube.com\/\watch\?v=/;
|
YOUTUBE_REGEX,
|
||||||
youtubeThumnbnail =
|
`https://img.youtube.com/vi/${youtubeId}/maxresdefault.jpg`
|
||||||
youtube.replace(regex, "img.youtube.com/vi/") + "/maxresdefault.jpg";
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (podcast && podcast.includes("life-itself")) {
|
const PodcastIcon = siteConfig.social.find((s) => s.name === "Podcast").icon;
|
||||||
const podcastUrl = podcast
|
|
||||||
podcastEmbed = ([
|
|
||||||
podcastUrl.slice(0, "https://anchor.fm/life-itself".length),
|
|
||||||
"/embed",
|
|
||||||
podcastUrl.slice("https://anchor.fm/life-itself".length)
|
|
||||||
].join(""))
|
|
||||||
}
|
|
||||||
|
|
||||||
const titleFromUrl = _raw.flattenedPath
|
const titleFromUrl = _raw.flattenedPath
|
||||||
.split("/")
|
.split("/")
|
||||||
|
|
@ -48,6 +49,11 @@ export default function MdxPage({ children, editUrl }) {
|
||||||
? siteConfig.url + image
|
? siteConfig.url + image
|
||||||
: youtubeThumnbnail ? youtubeThumnbnail : null
|
: youtubeThumnbnail ? youtubeThumnbnail : null
|
||||||
|
|
||||||
|
// enable editing content only for claims, concepts, and guide for now
|
||||||
|
const editUrl = ['claims', 'concepts', 'guide'].includes(_raw.sourceFileDir)
|
||||||
|
? siteConfig.repoRoot + siteConfig.repoEditPath + _raw.sourceFilePath
|
||||||
|
: null
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<NextSeo
|
<NextSeo
|
||||||
|
|
@ -57,6 +63,11 @@ export default function MdxPage({ children, editUrl }) {
|
||||||
openGraph={{
|
openGraph={{
|
||||||
title: SeoTitle,
|
title: SeoTitle,
|
||||||
description: description,
|
description: description,
|
||||||
|
url: `${siteConfig.url}/${_raw.flattenedPath}`,
|
||||||
|
type: "article",
|
||||||
|
article: {
|
||||||
|
tags: keywords ? keywords.split(",") : []
|
||||||
|
},
|
||||||
images: imageUrl
|
images: imageUrl
|
||||||
? ([
|
? ([
|
||||||
{
|
{
|
||||||
|
|
@ -69,16 +80,14 @@ export default function MdxPage({ children, editUrl }) {
|
||||||
])
|
])
|
||||||
: siteConfig.nextSeo.openGraph.images,
|
: siteConfig.nextSeo.openGraph.images,
|
||||||
}}
|
}}
|
||||||
|
additionalMetaTags={[
|
||||||
|
{ name: "keywords", content: keywords ? keywords : "" }
|
||||||
|
]}
|
||||||
/>
|
/>
|
||||||
<article className="prose dark:prose-invert prose-a:break-all mx-auto p-6">
|
<article className="prose dark:prose-invert prose-a:break-all mx-auto p-6">
|
||||||
<header>
|
<header>
|
||||||
<div className="mb-6">
|
<div className="mb-6">
|
||||||
{title && <h1 className="mb-0">{title}</h1>}
|
{title && <h1 className="mb-0">{title}</h1>}
|
||||||
{authors && (
|
|
||||||
<div className="-mt-6">
|
|
||||||
<p className="opacity-60 pl-1">{authors}</p>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
{date && (
|
{date && (
|
||||||
<p className="text-gray-900 dark:text-gray-500 text-sm pl-2">
|
<p className="text-gray-900 dark:text-gray-500 text-sm pl-2">
|
||||||
on {date}
|
on {date}
|
||||||
|
|
@ -87,36 +96,21 @@ export default function MdxPage({ children, editUrl }) {
|
||||||
{description && (
|
{description && (
|
||||||
<p className="">{description}</p>
|
<p className="">{description}</p>
|
||||||
)}
|
)}
|
||||||
{youtube && (
|
{youtubeId && (
|
||||||
<div className="relative pt-[56.25%]">
|
<LiteYouTubeEmbed id={youtubeId} />
|
||||||
<ReactPlayer
|
|
||||||
className="absolute top-0 left-0"
|
|
||||||
width="100%"
|
|
||||||
height="100%"
|
|
||||||
url={youtube}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
)}
|
)}
|
||||||
{podcast && (
|
{podcast && (
|
||||||
<div className="pt-4">
|
<div className="pt-4">
|
||||||
<ul className="list-disc">
|
<ul className="list-disc">
|
||||||
<li>
|
<li>
|
||||||
Podcast:
|
<a className="flex items-center" target="_blank" rel="noopener" href={podcast}>
|
||||||
<a href={podcast}>{podcast}</a>
|
<div className="w-4 mr-2">
|
||||||
|
<PodcastIcon />
|
||||||
|
</div>
|
||||||
|
<p className="m-0">Listen to this podcast</p>
|
||||||
|
</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
{podcastEmbed && (
|
|
||||||
<div className="md:mx-4">
|
|
||||||
<iframe
|
|
||||||
src={podcastEmbed}
|
|
||||||
height="100px"
|
|
||||||
width="100%"
|
|
||||||
frameBorder="0"
|
|
||||||
scrolling="no"
|
|
||||||
className="rounded-md"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -1,30 +1,15 @@
|
||||||
import ReactPlayer from "react-player";
|
import LiteYouTubeEmbed from "react-lite-youtube-embed";
|
||||||
|
import { YOUTUBE_REGEX } from "../lib/constants";
|
||||||
const videoLinks = [
|
|
||||||
"youtube.com",
|
|
||||||
"dailymotion.com",
|
|
||||||
"vimeo.com",
|
|
||||||
"soundcloud.com",
|
|
||||||
"facebook.com/watch",
|
|
||||||
"twitch.com",
|
|
||||||
];
|
|
||||||
|
|
||||||
export const Paragraph = (props) => {
|
export const Paragraph = (props) => {
|
||||||
if (
|
if (
|
||||||
typeof props.children == "object" &&
|
typeof props.children == "object" &&
|
||||||
props.children.props &&
|
props.children.props &&
|
||||||
props.children.props.href &&
|
props.children.props.href &&
|
||||||
videoLinks.some((str) => props.children.props.href.includes(str))
|
YOUTUBE_REGEX.test(props.children.props.href)
|
||||||
)
|
) {
|
||||||
return (
|
const youtubeId = props.children.props.href.split(/^|=|\//).pop();
|
||||||
<div className="relative pt-[56.25%]" {...props}>
|
return <LiteYouTubeEmbed id={youtubeId} />;
|
||||||
<ReactPlayer
|
}
|
||||||
className="absolute top-0 left-0"
|
|
||||||
width="100%"
|
|
||||||
height="100%"
|
|
||||||
url={props.children.props.href}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
return <p {...props} />;
|
return <p {...props} />;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,9 @@ import rehypeSlug from 'rehype-slug'
|
||||||
import rehypeAutolinkHeadings from 'rehype-autolink-headings'
|
import rehypeAutolinkHeadings from 'rehype-autolink-headings'
|
||||||
import wikiLinkPlugin from "remark-wiki-link-plus"
|
import wikiLinkPlugin from "remark-wiki-link-plus"
|
||||||
|
|
||||||
|
const isValidDate = dateObject => new Date(dateObject)
|
||||||
|
.toString() !== 'Invalid Date';
|
||||||
|
|
||||||
const ObsidianAliases = defineNestedType(() => ({
|
const ObsidianAliases = defineNestedType(() => ({
|
||||||
name: 'Obsidian',
|
name: 'Obsidian',
|
||||||
filePathPattern: '**/*.md*',
|
filePathPattern: '**/*.md*',
|
||||||
|
|
@ -22,6 +25,7 @@ const OtherPage = defineDocumentType(() => ({
|
||||||
date: { type: "date", description: "This will be the publication date" },
|
date: { type: "date", description: "This will be the publication date" },
|
||||||
image: { type: "string" },
|
image: { type: "string" },
|
||||||
description: { type: 'string' },
|
description: { type: 'string' },
|
||||||
|
keywords: { type: "string" },
|
||||||
youtube: { type: "string" },
|
youtube: { type: "string" },
|
||||||
podcast: { type: "string" },
|
podcast: { type: "string" },
|
||||||
featured: { type: "boolean", default: false },
|
featured: { type: "boolean", default: false },
|
||||||
|
|
@ -31,13 +35,19 @@ const OtherPage = defineDocumentType(() => ({
|
||||||
computedFields: {
|
computedFields: {
|
||||||
date: {
|
date: {
|
||||||
type: "date",
|
type: "date",
|
||||||
resolve: (doc) => new Date(doc.date).toLocaleDateString('en-US', {
|
resolve: (doc) => {
|
||||||
weekday: "long", year: "numeric", month: "long", day: "numeric"
|
const formattedDate = new Date(doc.date).toLocaleDateString('en-US', {
|
||||||
})
|
weekday: "long", year: "numeric", month: "long", day: "numeric"
|
||||||
|
})
|
||||||
|
return isValidDate(formattedDate) ? formattedDate : null
|
||||||
|
}
|
||||||
},
|
},
|
||||||
created: {
|
created: {
|
||||||
type: "date",
|
type: "date",
|
||||||
resolve: (doc) => new Date(doc.created).toLocaleDateString('en-US')
|
resolve: (doc) => {
|
||||||
|
const formattedDate = new Date(doc.created).toLocaleDateString('en-US')
|
||||||
|
return isValidDate(formattedDate) ? formattedDate : null
|
||||||
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,2 @@
|
||||||
|
export const YOUTUBE_REGEX =
|
||||||
|
/^.*((youtu.be\/)|(v\/)|(\/u\/\w\/)|(embed\/)|(watch\?))\??v?=?([^#\&\?]*).*/;
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -3,6 +3,7 @@
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "next dev",
|
"dev": "next dev",
|
||||||
"build": "next build",
|
"build": "next build",
|
||||||
|
"postbuild": "NODE_OPTIONS='--experimental-json-modules' node ./scripts/generate-sitemap.mjs",
|
||||||
"export": "next export",
|
"export": "next export",
|
||||||
"start": "next start"
|
"start": "next start"
|
||||||
},
|
},
|
||||||
|
|
@ -10,34 +11,31 @@
|
||||||
"@floating-ui/react-dom-interactions": "^0.6.0",
|
"@floating-ui/react-dom-interactions": "^0.6.0",
|
||||||
"@headlessui/react": "^1.4.1",
|
"@headlessui/react": "^1.4.1",
|
||||||
"@heroicons/react": "^1.0.4",
|
"@heroicons/react": "^1.0.4",
|
||||||
"@mdx-js/loader": "^2.0.0",
|
|
||||||
"@mdx-js/react": "^2.0.0",
|
|
||||||
"@next/mdx": "^12.1.0",
|
|
||||||
"@silvenon/remark-smartypants": "^1.0.0",
|
|
||||||
"@tailwindcss/typography": "^0.5.2",
|
"@tailwindcss/typography": "^0.5.2",
|
||||||
"contentlayer": "^0.1.2",
|
"contentlayer": "^0.1.2",
|
||||||
"framer-motion": "^6.3.3",
|
"framer-motion": "^6.3.3",
|
||||||
"gray-matter": "^4.0.3",
|
"gray-matter": "^4.0.3",
|
||||||
"hast-util-to-string": "^2.0.0",
|
|
||||||
"next": "^12.1.0",
|
"next": "^12.1.0",
|
||||||
"next-contentlayer": "^0.1.2",
|
"next-contentlayer": "^0.1.2",
|
||||||
"next-seo": "^4.28.1",
|
"next-seo": "^4.28.1",
|
||||||
"next-themes": "^0.1.1",
|
"next-themes": "^0.1.1",
|
||||||
"react": "^17.0.2",
|
"react": "^17.0.2",
|
||||||
"react-dom": "^17.0.2",
|
"react-dom": "^17.0.2",
|
||||||
"react-player": "^2.10.0",
|
"react-lite-youtube-embed": "^2.2.2",
|
||||||
|
"sharp": "^0.30.5"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"autoprefixer": "^10.2.6",
|
||||||
|
"globby": "^13.1.1",
|
||||||
|
"hast-util-to-string": "^2.0.0",
|
||||||
|
"postcss": "^8.3.5",
|
||||||
|
"prettier": "^2.6.2",
|
||||||
"rehype-autolink-headings": "^6.1.1",
|
"rehype-autolink-headings": "^6.1.1",
|
||||||
"rehype-slug": "^5.0.1",
|
"rehype-slug": "^5.0.1",
|
||||||
"remark-gfm": "^3.0.0",
|
"remark-gfm": "^3.0.0",
|
||||||
"remark-parse": "^10.0.1",
|
"remark-parse": "^10.0.1",
|
||||||
"remark-slug": "^7.0.0",
|
|
||||||
"remark-toc": "^8.0.0",
|
|
||||||
"remark-wiki-link-plus": "^1.0.0",
|
"remark-wiki-link-plus": "^1.0.0",
|
||||||
|
"tailwindcss": "^3.0.0",
|
||||||
"unist-util-find": "^1.0.2"
|
"unist-util-find": "^1.0.2"
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"autoprefixer": "^10.2.6",
|
|
||||||
"postcss": "^8.3.5",
|
|
||||||
"tailwindcss": "^3.0.0"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
import MdxPage from '../components/MDX';
|
import MdxPage from '../components/MDX';
|
||||||
import { allOtherPages } from 'contentlayer/generated';
|
import { allOtherPages } from 'contentlayer/generated';
|
||||||
import { useMDXComponent } from 'next-contentlayer/hooks';
|
import { useMDXComponent } from 'next-contentlayer/hooks';
|
||||||
import siteConfig from "../config/siteConfig"
|
|
||||||
|
|
||||||
|
|
||||||
export default function Page({ body, ...rest }) {
|
export default function Page({ body, ...rest }) {
|
||||||
|
|
@ -9,19 +8,12 @@ export default function Page({ body, ...rest }) {
|
||||||
const children = {
|
const children = {
|
||||||
Component,
|
Component,
|
||||||
frontmatter: {
|
frontmatter: {
|
||||||
...rest,
|
...rest
|
||||||
date: rest.date === "Invalid Date" ? null : rest.date,
|
|
||||||
created: rest.created === "Invalid Date" ? null : rest.created
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
// enable editing content only for claims, concepts, and guide for now
|
|
||||||
const editUrl = ['claims', 'concepts', 'guide'].includes(rest._raw.sourceFileDir)
|
|
||||||
? siteConfig.repoRoot + siteConfig.repoEditPath + rest._raw.sourceFilePath
|
|
||||||
: null
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<MdxPage children={children} editUrl={editUrl} />
|
<MdxPage children={children} />
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ import { DefaultSeo } from 'next-seo'
|
||||||
import { ThemeProvider } from 'next-themes'
|
import { ThemeProvider } from 'next-themes'
|
||||||
|
|
||||||
import '../styles/global.css'
|
import '../styles/global.css'
|
||||||
|
import "react-lite-youtube-embed/dist/LiteYouTubeEmbed.css";
|
||||||
import siteConfig from '../config/siteConfig.js'
|
import siteConfig from '../config/siteConfig.js'
|
||||||
import Layout from '../components/Layout'
|
import Layout from '../components/Layout'
|
||||||
import * as gtag from '../lib/gtag'
|
import * as gtag from '../lib/gtag'
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:29d50bf63165133404309fea97324eff18a7cd86a3172d39e0c3d0cd635b62fe
|
||||||
|
size 141203
|
||||||
|
|
@ -1,3 +0,0 @@
|
||||||
version https://git-lfs.github.com/spec/v1
|
|
||||||
oid sha256:df3e54f72d5eea93eda159366a0c5d561db0e259c3125c3d49e20c3da433b8ea
|
|
||||||
size 1107869
|
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:18bf3b1fb17ea49bd7a616d992245f40e34eba33e5e49739c1bbe32cc2970054
|
||||||
|
size 60178
|
||||||
|
|
@ -1,3 +0,0 @@
|
||||||
version https://git-lfs.github.com/spec/v1
|
|
||||||
oid sha256:4d4728d0239c3103ca7cd6da93a0ad6d2f69f3df0f6bebeac72e44bf36105e0b
|
|
||||||
size 27545
|
|
||||||
|
|
@ -0,0 +1,45 @@
|
||||||
|
import { writeFileSync } from "fs";
|
||||||
|
import { globby } from "globby";
|
||||||
|
import prettier from "prettier";
|
||||||
|
|
||||||
|
async function generate() {
|
||||||
|
const prettierConfig = await prettier.resolveConfig("./.prettierrc.js");
|
||||||
|
const pages = await globby([
|
||||||
|
"pages/!(\\[**])*.js*",
|
||||||
|
"content/**/*.md*",
|
||||||
|
"!pages/_*.js*",
|
||||||
|
"!pages/api",
|
||||||
|
"!pages/404.js*",
|
||||||
|
]);
|
||||||
|
|
||||||
|
const sitemap = `
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
||||||
|
${pages
|
||||||
|
.map((page) => {
|
||||||
|
const path = page
|
||||||
|
.replace("pages", "")
|
||||||
|
.replace("content", "")
|
||||||
|
.replace(/.jsx*/, "")
|
||||||
|
.replace(/.mdx*/, "");
|
||||||
|
const route = path === "/index" ? "" : path;
|
||||||
|
return `
|
||||||
|
<url>
|
||||||
|
<loc>${`https://web3.lifeiteself.us${route}`}</loc>
|
||||||
|
</url>
|
||||||
|
`;
|
||||||
|
})
|
||||||
|
.join("")}
|
||||||
|
</urlset>
|
||||||
|
`;
|
||||||
|
|
||||||
|
const formatted = prettier.format(sitemap, {
|
||||||
|
...prettierConfig,
|
||||||
|
parser: "html",
|
||||||
|
});
|
||||||
|
|
||||||
|
// eslint-disable-next-line no-sync
|
||||||
|
writeFileSync("public/sitemap.xml", formatted);
|
||||||
|
}
|
||||||
|
|
||||||
|
generate();
|
||||||
Loading…
Reference in New Issue