upstream #1
2
.gitignore
vendored
2
.gitignore
vendored
@ -17,6 +17,8 @@ public/sitemap.xml
|
|||||||
# production
|
# production
|
||||||
/build
|
/build
|
||||||
*.xml
|
*.xml
|
||||||
|
# rss feed
|
||||||
|
/public/index.xml
|
||||||
|
|
||||||
# misc
|
# misc
|
||||||
.DS_Store
|
.DS_Store
|
||||||
|
0
.husky/pre-commit
Normal file → Executable file
0
.husky/pre-commit
Normal file → Executable file
@ -34,6 +34,7 @@ I wanted it to be nearly as feature-rich as popular blogging templates like [bea
|
|||||||
- Automatic image optimization via [next/image](https://nextjs.org/docs/basic-features/image-optimization)
|
- Automatic image optimization via [next/image](https://nextjs.org/docs/basic-features/image-optimization)
|
||||||
- Flexible data retrieval with [next-mdx-remote](https://github.com/hashicorp/next-mdx-remote)
|
- Flexible data retrieval with [next-mdx-remote](https://github.com/hashicorp/next-mdx-remote)
|
||||||
- Support for tags - each unique tag will be its own page
|
- Support for tags - each unique tag will be its own page
|
||||||
|
- Support for nested routing of blog posts
|
||||||
- Projects page
|
- Projects page
|
||||||
- SEO friendly with RSS feed, sitemaps and more!
|
- SEO friendly with RSS feed, sitemaps and more!
|
||||||
|
|
||||||
@ -44,6 +45,7 @@ I wanted it to be nearly as feature-rich as popular blogging templates like [bea
|
|||||||
- [A tour of math typesetting](https://tailwind-nextjs-starter-blog.vercel.app/blog/deriving-ols-estimator)
|
- [A tour of math typesetting](https://tailwind-nextjs-starter-blog.vercel.app/blog/deriving-ols-estimator)
|
||||||
- [Simple MDX image grid](https://tailwind-nextjs-starter-blog.vercel.app/blog/pictures-of-canada)
|
- [Simple MDX image grid](https://tailwind-nextjs-starter-blog.vercel.app/blog/pictures-of-canada)
|
||||||
- [Example of long prose](https://tailwind-nextjs-starter-blog.vercel.app/blog/the-time-machine)
|
- [Example of long prose](https://tailwind-nextjs-starter-blog.vercel.app/blog/the-time-machine)
|
||||||
|
- [Example of Nested Route Post](https://tailwind-nextjs-starter-blog.vercel.app/blog/nested-route/introducing-multi-part-posts-with-nested-routing)
|
||||||
|
|
||||||
## Quick Start Guide
|
## Quick Start Guide
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import Link from 'next/link'
|
import Link from 'next/link'
|
||||||
import { kebabCase } from '@/lib/utils'
|
import kebabCase from '@/lib/utils/kebabCase'
|
||||||
|
|
||||||
const Tag = ({ text }) => {
|
const Tag = ({ text }) => {
|
||||||
return (
|
return (
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
---
|
---
|
||||||
title: 'Introducing Tailwind Nexjs Starter Blog'
|
title: 'Introducing Tailwind Nexjs Starter Blog'
|
||||||
date: '2021-01-12'
|
date: '2021-01-12'
|
||||||
lastmod: '2021-01-18'
|
lastmod: '2021-05-08'
|
||||||
tags: ['next-js', 'tailwind', 'guide']
|
tags: ['next-js', 'tailwind', 'guide']
|
||||||
draft: false
|
draft: false
|
||||||
summary: 'Looking for a performant, out of the box template, with all the best in web technology to support your blogging needs? Checkout the Tailwind Nextjs Starter Blog template.'
|
summary: 'Looking for a performant, out of the box template, with all the best in web technology to support your blogging needs? Checkout the Tailwind Nextjs Starter Blog template.'
|
||||||
@ -44,6 +44,7 @@ I wanted it to be nearly as feature-rich as popular blogging templates like [bea
|
|||||||
- Automatic image optimization via [next/image](https://nextjs.org/docs/basic-features/image-optimization)
|
- Automatic image optimization via [next/image](https://nextjs.org/docs/basic-features/image-optimization)
|
||||||
- Flexible data retrieval with [next-mdx-remote](https://github.com/hashicorp/next-mdx-remote)
|
- Flexible data retrieval with [next-mdx-remote](https://github.com/hashicorp/next-mdx-remote)
|
||||||
- Support for tags - each unique tag will be its own page
|
- Support for tags - each unique tag will be its own page
|
||||||
|
- Support for nested routing of blog posts
|
||||||
- SEO friendly with RSS feed, sitemaps and more!
|
- SEO friendly with RSS feed, sitemaps and more!
|
||||||
|
|
||||||
## Sample posts
|
## Sample posts
|
||||||
@ -53,6 +54,7 @@ I wanted it to be nearly as feature-rich as popular blogging templates like [bea
|
|||||||
- [A tour of math typesetting](/blog/deriving-ols-estimator)
|
- [A tour of math typesetting](/blog/deriving-ols-estimator)
|
||||||
- [Simple MDX image grid](/blog/pictures-of-canada)
|
- [Simple MDX image grid](/blog/pictures-of-canada)
|
||||||
- [Example of long prose](/blog/the-time-machine)
|
- [Example of long prose](/blog/the-time-machine)
|
||||||
|
- [Example of Nested Route Post](/blog/nested-route/introducing-multi-part-posts-with-nested-routing)
|
||||||
|
|
||||||
## Quick Start Guide
|
## Quick Start Guide
|
||||||
|
|
||||||
|
@ -0,0 +1,30 @@
|
|||||||
|
---
|
||||||
|
title: Introducing Multi-part Posts with Nested Routing
|
||||||
|
date: '2021-05-02'
|
||||||
|
tags: ['multi-author', 'next-js', 'feature']
|
||||||
|
draft: false
|
||||||
|
summary: 'The blog template supports posts in nested sub-folders. This can be used to group posts of similar content e.g. a multi-part course. This post is itself an example of a nested route!'
|
||||||
|
---
|
||||||
|
|
||||||
|
# Nested Routes
|
||||||
|
|
||||||
|
The blog template supports posts in nested sub-folders. This helps in organisation and can be used to group posts of similar content e.g. a multi-part series. This post is itself an example of a nested route! It's located in the `/data/blog/nested-route` folder.
|
||||||
|
|
||||||
|
## How
|
||||||
|
|
||||||
|
Simplify create multiple folders inside the main `/data/blog` folder and add your `.md`/`.mdx` files to them. You can even create something like `/data/blog/nested-route/deeply-nested-route/my-post.md`
|
||||||
|
|
||||||
|
We use Next.js catch all routes to handle the routing and path creations.
|
||||||
|
|
||||||
|
## Use Cases
|
||||||
|
|
||||||
|
Here's some reasons to use nested routes
|
||||||
|
|
||||||
|
- More logical content organisation (blogs will still be displayed based on the created date)
|
||||||
|
- Multi-part posts
|
||||||
|
- Different sub-routes for each author
|
||||||
|
- Internationalization (though it would be recommended to use [Next.js built in i8n routing](https://nextjs.org/docs/advanced-features/i18n-routing))
|
||||||
|
|
||||||
|
## Note
|
||||||
|
|
||||||
|
- The previous/next post links at bottom of the template is currently sorted by date. One could explore modifying the template to refer the reader to the previous/next post in the series, rather than by date.
|
30
lib/mdx.js
30
lib/mdx.js
@ -1,12 +1,12 @@
|
|||||||
|
import MDXComponents from '@/components/MDXComponents'
|
||||||
import fs from 'fs'
|
import fs from 'fs'
|
||||||
import matter from 'gray-matter'
|
import matter from 'gray-matter'
|
||||||
import visit from 'unist-util-visit'
|
import renderToString from 'next-mdx-remote/render-to-string'
|
||||||
import path from 'path'
|
import path from 'path'
|
||||||
import readingTime from 'reading-time'
|
import readingTime from 'reading-time'
|
||||||
import renderToString from 'next-mdx-remote/render-to-string'
|
import visit from 'unist-util-visit'
|
||||||
|
|
||||||
import MDXComponents from '@/components/MDXComponents'
|
|
||||||
import imgToJsx from './img-to-jsx'
|
import imgToJsx from './img-to-jsx'
|
||||||
|
import getAllFilesRecursively from './utils/files'
|
||||||
|
|
||||||
const root = process.cwd()
|
const root = process.cwd()
|
||||||
|
|
||||||
@ -24,8 +24,11 @@ const tokenClassNames = {
|
|||||||
comment: 'text-gray-400 italic',
|
comment: 'text-gray-400 italic',
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getFiles(type) {
|
export function getFiles(type) {
|
||||||
return fs.readdirSync(path.join(root, 'data', type))
|
const prefixPaths = path.join(root, 'data', type)
|
||||||
|
const files = getAllFilesRecursively(prefixPaths)
|
||||||
|
// Only want to return blog/path and ignore root
|
||||||
|
return files.map(file => file.slice(prefixPaths.length + 1))
|
||||||
}
|
}
|
||||||
|
|
||||||
export function formatSlug(slug) {
|
export function formatSlug(slug) {
|
||||||
@ -39,8 +42,8 @@ export function dateSortDesc(a, b) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function getFileBySlug(type, slug) {
|
export async function getFileBySlug(type, slug) {
|
||||||
const mdxPath = path.join(root, 'data', type, `${slug}.mdx`)
|
const mdxPath = path.join(root, 'data', type, `${slug.join('/')}.mdx`)
|
||||||
const mdPath = path.join(root, 'data', type, `${slug}.md`)
|
const mdPath = path.join(root, 'data', type, `${slug.join('/')}.md`)
|
||||||
const source = fs.existsSync(mdxPath)
|
const source = fs.existsSync(mdxPath)
|
||||||
? fs.readFileSync(mdxPath, 'utf8')
|
? fs.readFileSync(mdxPath, 'utf8')
|
||||||
: fs.readFileSync(mdPath, 'utf8')
|
: fs.readFileSync(mdPath, 'utf8')
|
||||||
@ -86,16 +89,19 @@ export async function getFileBySlug(type, slug) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getAllFilesFrontMatter(type) {
|
export async function getAllFilesFrontMatter(folder) {
|
||||||
const files = fs.readdirSync(path.join(root, 'data', type))
|
const prefixPaths = path.join(root, 'data', folder)
|
||||||
|
|
||||||
|
const files = getAllFilesRecursively(prefixPaths)
|
||||||
|
|
||||||
const allFrontMatter = []
|
const allFrontMatter = []
|
||||||
|
|
||||||
files.forEach((file) => {
|
files.forEach((file) => {
|
||||||
const source = fs.readFileSync(path.join(root, 'data', type, file), 'utf8')
|
const fileName = file.slice(prefixPaths.length + 1)
|
||||||
|
const source = fs.readFileSync(file, 'utf8')
|
||||||
const { data } = matter(source)
|
const { data } = matter(source)
|
||||||
if (data.draft !== true) {
|
if (data.draft !== true) {
|
||||||
allFrontMatter.push({ ...data, slug: formatSlug(file) })
|
allFrontMatter.push({ ...data, slug: formatSlug(fileName) })
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -1,12 +1,13 @@
|
|||||||
import fs from 'fs'
|
import fs from 'fs'
|
||||||
import matter from 'gray-matter'
|
import matter from 'gray-matter'
|
||||||
import path from 'path'
|
import path from 'path'
|
||||||
import { kebabCase } from './utils'
|
import { getFiles } from './mdx'
|
||||||
|
import kebabCase from './utils/kebabCase'
|
||||||
|
|
||||||
const root = process.cwd()
|
const root = process.cwd()
|
||||||
|
|
||||||
export async function getAllTags(type) {
|
export async function getAllTags(type) {
|
||||||
const files = fs.readdirSync(path.join(root, 'data', type))
|
const files = await getFiles(type)
|
||||||
|
|
||||||
let tagCount = {}
|
let tagCount = {}
|
||||||
// Iterate through each post, putting all found tags into `tags`
|
// Iterate through each post, putting all found tags into `tags`
|
||||||
|
20
lib/utils/files.js
Normal file
20
lib/utils/files.js
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
import fs from 'fs'
|
||||||
|
import path from 'path'
|
||||||
|
|
||||||
|
const pipe = (...fns) => (x) => fns.reduce((v, f) => f(v), x)
|
||||||
|
|
||||||
|
const flatternArray = (input) =>
|
||||||
|
input.reduce((acc, item) => [...acc, ...(Array.isArray(item) ? item : [item])], [])
|
||||||
|
|
||||||
|
const map = (fn) => (input) => input.map(fn)
|
||||||
|
|
||||||
|
const walkDir = (fullPath) => {
|
||||||
|
return fs.statSync(fullPath).isFile() ? fullPath : getAllFilesRecursively(fullPath)
|
||||||
|
}
|
||||||
|
|
||||||
|
const pathJoinPrefix = (prefix) => (extraPath) => path.join(prefix, extraPath)
|
||||||
|
|
||||||
|
const getAllFilesRecursively = (folder) =>
|
||||||
|
pipe(fs.readdirSync, map(pipe(pathJoinPrefix(folder), walkDir)), flatternArray)(folder)
|
||||||
|
|
||||||
|
export default getAllFilesRecursively
|
@ -1,6 +1,8 @@
|
|||||||
export const kebabCase = (str) =>
|
const kebabCase = (str) =>
|
||||||
str &&
|
str &&
|
||||||
str
|
str
|
||||||
.match(/[A-Z]{2,}(?=[A-Z][a-z]+[0-9]*|\b)|[A-Z]?[a-z]+[0-9]*|[A-Z]|[0-9]+/g)
|
.match(/[A-Z]{2,}(?=[A-Z][a-z]+[0-9]*|\b)|[A-Z]?[a-z]+[0-9]*|[A-Z]|[0-9]+/g)
|
||||||
.map((x) => x.toLowerCase())
|
.map((x) => x.toLowerCase())
|
||||||
.join('-')
|
.join('-')
|
||||||
|
|
||||||
|
export default kebabCase
|
@ -1,18 +1,17 @@
|
|||||||
import fs from 'fs'
|
|
||||||
import hydrate from 'next-mdx-remote/hydrate'
|
|
||||||
import { getFiles, getFileBySlug, getAllFilesFrontMatter, formatSlug } from '@/lib/mdx'
|
|
||||||
import PostLayout from '@/layouts/PostLayout'
|
|
||||||
import MDXComponents from '@/components/MDXComponents'
|
import MDXComponents from '@/components/MDXComponents'
|
||||||
import PageTitle from '@/components/PageTitle'
|
import PageTitle from '@/components/PageTitle'
|
||||||
|
import PostLayout from '@/layouts/PostLayout'
|
||||||
import generateRss from '@/lib/generate-rss'
|
import generateRss from '@/lib/generate-rss'
|
||||||
|
import { formatSlug, getAllFilesFrontMatter, getFileBySlug, getFiles } from '@/lib/mdx'
|
||||||
|
import fs from 'fs'
|
||||||
|
import hydrate from 'next-mdx-remote/hydrate'
|
||||||
|
|
||||||
export async function getStaticPaths() {
|
export async function getStaticPaths() {
|
||||||
const posts = await getFiles('blog')
|
const posts = getFiles('blog')
|
||||||
|
|
||||||
return {
|
return {
|
||||||
paths: posts.map((p) => ({
|
paths: posts.map((p) => ({
|
||||||
params: {
|
params: {
|
||||||
slug: formatSlug(p),
|
slug: formatSlug(p).split('/'),
|
||||||
},
|
},
|
||||||
})),
|
})),
|
||||||
fallback: false,
|
fallback: false,
|
||||||
@ -21,7 +20,7 @@ export async function getStaticPaths() {
|
|||||||
|
|
||||||
export async function getStaticProps({ params }) {
|
export async function getStaticProps({ params }) {
|
||||||
const allPosts = await getAllFilesFrontMatter('blog')
|
const allPosts = await getAllFilesFrontMatter('blog')
|
||||||
const postIndex = allPosts.findIndex((post) => post.slug === params.slug)
|
const postIndex = allPosts.findIndex((post) => formatSlug(post.slug) === params.slug.join('/'))
|
||||||
const prev = allPosts[postIndex + 1] || null
|
const prev = allPosts[postIndex + 1] || null
|
||||||
const next = allPosts[postIndex - 1] || null
|
const next = allPosts[postIndex - 1] || null
|
||||||
const post = await getFileBySlug('blog', params.slug)
|
const post = await getFileBySlug('blog', params.slug)
|
@ -1,9 +1,9 @@
|
|||||||
import siteMetadata from '@/data/siteMetadata'
|
|
||||||
import { kebabCase } from '@/lib/utils'
|
|
||||||
import { getAllTags } from '@/lib/tags'
|
|
||||||
import Tag from '@/components/Tag'
|
|
||||||
import Link from '@/components/Link'
|
import Link from '@/components/Link'
|
||||||
import { PageSeo } from '@/components/SEO'
|
import { PageSeo } from '@/components/SEO'
|
||||||
|
import Tag from '@/components/Tag'
|
||||||
|
import siteMetadata from '@/data/siteMetadata'
|
||||||
|
import { getAllTags } from '@/lib/tags'
|
||||||
|
import kebabCase from '@/lib/utils/kebabCase'
|
||||||
|
|
||||||
export async function getStaticProps() {
|
export async function getStaticProps() {
|
||||||
const tags = await getAllTags('blog')
|
const tags = await getAllTags('blog')
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
import fs from 'fs'
|
import { PageSeo } from '@/components/SEO'
|
||||||
import path from 'path'
|
|
||||||
import { kebabCase } from '@/lib/utils'
|
|
||||||
import { getAllFilesFrontMatter } from '@/lib/mdx'
|
|
||||||
import { getAllTags } from '@/lib/tags'
|
|
||||||
import siteMetadata from '@/data/siteMetadata'
|
import siteMetadata from '@/data/siteMetadata'
|
||||||
import ListLayout from '@/layouts/ListLayout'
|
import ListLayout from '@/layouts/ListLayout'
|
||||||
import { PageSeo } from '@/components/SEO'
|
|
||||||
import generateRss from '@/lib/generate-rss'
|
import generateRss from '@/lib/generate-rss'
|
||||||
|
import { getAllFilesFrontMatter } from '@/lib/mdx'
|
||||||
|
import { getAllTags } from '@/lib/tags'
|
||||||
|
import kebabCase from '@/lib/utils/kebabCase'
|
||||||
|
import fs from 'fs'
|
||||||
|
import path from 'path'
|
||||||
|
|
||||||
const root = process.cwd()
|
const root = process.cwd()
|
||||||
|
|
||||||
|
@ -1,84 +0,0 @@
|
|||||||
|
|
||||||
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
|
|
||||||
<channel>
|
|
||||||
<title>Next.js Starter Blog</title>
|
|
||||||
<link>https://tailwind-nextjs-starter-blog.vercel.app/blog</link>
|
|
||||||
<description>A blog created with Next.js and Tailwind.css</description>
|
|
||||||
<language>en-us</language>
|
|
||||||
<managingEditor>address@yoursite.com (Tails Azimuth)</managingEditor>
|
|
||||||
<webMaster>address@yoursite.com (Tails Azimuth)</webMaster>
|
|
||||||
<lastBuildDate>Tue, 12 Jan 2021 00:00:00 GMT</lastBuildDate>
|
|
||||||
<atom:link href="https://tailwind-nextjs-starter-blog.vercel.app/index.xml" rel="self" type="application/rss+xml"/>
|
|
||||||
|
|
||||||
<item>
|
|
||||||
<guid>https://tailwind-nextjs-starter-blog.vercel.app/blog/introducing-tailwind-nextjs-starter-blog</guid>
|
|
||||||
<title>Introducing Tailwind Nexjs Starter Blog</title>
|
|
||||||
<link>https://tailwind-nextjs-starter-blog.vercel.app/blog/introducing-tailwind-nextjs-starter-blog</link>
|
|
||||||
<description>Looking for a performant, out of the box template, with all the best in web technology to support your blogging needs? Checkout the Tailwind Nextjs Starter Blog template.</description>
|
|
||||||
<pubDate>Tue, 12 Jan 2021 00:00:00 GMT</pubDate>
|
|
||||||
<author>address@yoursite.com (Tails Azimuth)</author>
|
|
||||||
<category>next-js</category><category>tailwind</category><category>guide</category>
|
|
||||||
</item>
|
|
||||||
|
|
||||||
<item>
|
|
||||||
<guid>https://tailwind-nextjs-starter-blog.vercel.app/blog/guide-to-using-images-in-nextjs</guid>
|
|
||||||
<title>Images in Next.js</title>
|
|
||||||
<link>https://tailwind-nextjs-starter-blog.vercel.app/blog/guide-to-using-images-in-nextjs</link>
|
|
||||||
<description>In this article we introduce adding images in the tailwind starter blog and the benefits and limitations of the next/image component.</description>
|
|
||||||
<pubDate>Wed, 11 Nov 2020 00:00:00 GMT</pubDate>
|
|
||||||
<author>address@yoursite.com (Tails Azimuth)</author>
|
|
||||||
<category>next js</category><category>guide</category>
|
|
||||||
</item>
|
|
||||||
|
|
||||||
<item>
|
|
||||||
<guid>https://tailwind-nextjs-starter-blog.vercel.app/blog/deriving-ols-estimator</guid>
|
|
||||||
<title>Deriving the OLS Estimator</title>
|
|
||||||
<link>https://tailwind-nextjs-starter-blog.vercel.app/blog/deriving-ols-estimator</link>
|
|
||||||
<description>How to derive the OLS Estimator with matrix notation and a tour of math typesetting using markdown with the help of KaTeX.</description>
|
|
||||||
<pubDate>Sat, 16 Nov 2019 00:00:00 GMT</pubDate>
|
|
||||||
<author>address@yoursite.com (Tails Azimuth)</author>
|
|
||||||
<category>next js</category><category>math</category><category>ols</category>
|
|
||||||
</item>
|
|
||||||
|
|
||||||
<item>
|
|
||||||
<guid>https://tailwind-nextjs-starter-blog.vercel.app/blog/github-markdown-guide</guid>
|
|
||||||
<title>Markdown Guide</title>
|
|
||||||
<link>https://tailwind-nextjs-starter-blog.vercel.app/blog/github-markdown-guide</link>
|
|
||||||
<description>Markdown cheatsheet for all your blogging needs - headers, lists, images, tables and more! An illustrated guide based on Github Flavored Markdown.</description>
|
|
||||||
<pubDate>Fri, 11 Oct 2019 00:00:00 GMT</pubDate>
|
|
||||||
<author>address@yoursite.com (Tails Azimuth)</author>
|
|
||||||
<category>github</category><category>guide</category>
|
|
||||||
</item>
|
|
||||||
|
|
||||||
<item>
|
|
||||||
<guid>https://tailwind-nextjs-starter-blog.vercel.app/blog/the-time-machine</guid>
|
|
||||||
<title>The Time Machine</title>
|
|
||||||
<link>https://tailwind-nextjs-starter-blog.vercel.app/blog/the-time-machine</link>
|
|
||||||
<description>The Time Traveller (for so it will be convenient to speak of him) was expounding a recondite matter to us. His pale grey eyes shone and twinkled, and his usually pale face was flushed and animated...</description>
|
|
||||||
<pubDate>Wed, 15 Aug 2018 00:00:00 GMT</pubDate>
|
|
||||||
<author>address@yoursite.com (Tails Azimuth)</author>
|
|
||||||
<category>writings</category><category>book</category><category>reflection</category>
|
|
||||||
</item>
|
|
||||||
|
|
||||||
<item>
|
|
||||||
<guid>https://tailwind-nextjs-starter-blog.vercel.app/blog/pictures-of-canada</guid>
|
|
||||||
<title>O Canada</title>
|
|
||||||
<link>https://tailwind-nextjs-starter-blog.vercel.app/blog/pictures-of-canada</link>
|
|
||||||
<description>The scenic lands of Canada featuring maple leaves, snow-capped mountains, turquoise lakes and Toronto. Take in the sights in this photo gallery exhibition and see how easy it is to replicate with some MDX magic and tailwind classes.</description>
|
|
||||||
<pubDate>Sat, 15 Jul 2017 00:00:00 GMT</pubDate>
|
|
||||||
<author>address@yoursite.com (Tails Azimuth)</author>
|
|
||||||
<category>holiday</category><category>canada</category><category>images</category>
|
|
||||||
</item>
|
|
||||||
|
|
||||||
<item>
|
|
||||||
<guid>https://tailwind-nextjs-starter-blog.vercel.app/blog/code-sample</guid>
|
|
||||||
<title>Sample .md file</title>
|
|
||||||
<link>https://tailwind-nextjs-starter-blog.vercel.app/blog/code-sample</link>
|
|
||||||
<description>Example of a markdown file with code blocks and syntax highlighting</description>
|
|
||||||
<pubDate>Tue, 08 Mar 2016 00:00:00 GMT</pubDate>
|
|
||||||
<author>address@yoursite.com (Tails Azimuth)</author>
|
|
||||||
<category>markdown</category><category>code</category><category>features</category>
|
|
||||||
</item>
|
|
||||||
|
|
||||||
</channel>
|
|
||||||
</rss>
|
|
Loading…
x
Reference in New Issue
Block a user