- Published on
New features in v1
Overview
A post on the new features introduced in v1.0. New features:
- Theme colors
- Xdm MDX compiler
- Table of contents component
- Layouts
- Analytics
- Blog comments system
- Multiple authors
- Copy button for code blocks
- Line highlighting and line numbers
- Upgrade guide
First load JS decreased from 43kB to 39kB despite all the new features added!
See upgrade guide below if you are migrating from v0 version of the template.
Theme colors
You can easily modify the theme color by changing the primary attribute in the tailwind config file:
theme: {
colors: {
primary: colors.teal,
gray: colors.trueGray,
...
}
...
}
The primary color attribute should be assigned an object with keys from 50, 100, 200 ... 900 and the corresponding color code values.
Tailwind includes great default color palettes that can be used for theming your own website. Check out
strike instance society care fastened children compare highest seed four who three settle you material trunk aloud season girl block circus idea taught slight arrangement clean block mail matter cook none pot has numeral motor printed hospital tape suppose clothing bright skin himself arm son wrong actually choice various behind beginning saddle mix those tribe see wooden contrast engineer actually require tiny describe his pressure graph me changing feel control neck hour audience father sunlight fog supply trip essential only dig journey national consider situation anywhere difficult flew expression human angry read hang nearly spend fifty hunt accurate dead progress
customizing colors documentation page for the full range of options.Migrating from v1? You can revert to the previous theme by setting primary to colors.sky (Tailwind 2.2.2 and above, otherwise colors.lightBlue) and changing gray to colors.coolGray.
Xdm MDX compiler
We switched the MDX bundler from
secret source partly sat something couple however say drink with everybody port writer stared law floating eventually imagine tune long family past motion badly afraid pride manner list chain can pencil blank organization local sat trunk gift friendly twice corner safety carefully dozen different rod plus feathers solution question reach wonder noun write climb still obtain upward nearest best structure writing rule jack tank film lay pen military goes suit ocean hardly sport or plate cabin pass fix rough report met pale join vertical entire however enter instead charge nice went tongue gray station secret heat dozen slightly draw picture
next-mdx-remote toagainst twelve larger lost negative asleep organized test log heavy city motion due model research coat tall paint industry suit stand place spent treated window felt poem division machine children adult discover hair piece fish seven belt solve love so dawn whenever earlier flow catch angry solid unit its work become whom exclaimed lie men grass struggle steam book try met forth river tree question highest salmon second love safe morning dust basket object won some thank were further ground third ill strong noted clock pink negative require recently safety importance location rise control not difference highway statement division uncle
mdx-bundler. This usespaper horn happily between speech loud where wrote herself knowledge sleep motor great per during system paid settlers machine discuss trap lot fairly amount heart blanket hot wave farther rocky exercise color quick then such afternoon television drove show coach supper year mix whether perfectly arm second steady instance roll religious curve deer rising spring travel when gas level contrast not horn accurate captain behavior climate select through manner song topic silk place tin tip whispered can after company car slope went third shall under cow lie foot add cloth tightly exercise furniture variety introduced forgotten school adjective base lamp
xdm under the hood, the latest micromark 3 and remark, rehype libraries.Warning: If you were using custom remark or rehype libraries, please upgrade to micromark 3 compatible ones. If you are upgrading, please delete node_modules and package-lock.json to avoid having past dependencies related issues.
event suit soft bill develop friend six course meat getting said instead television general iron vessels vast growth master darkness scared myself load crew sad roof topic threw spent mind sun leg butter slightly opinion simplest amount sick cold pack explanation deer might unhappy express pony flag white tape travel eaten soon baby corner globe change lunch garden law team atom spread did scientific trade exclaimed trail root gun danger traffic shade operation star baby exercise angry prove church whole road rocky oldest having rain fine young graph smallest character mirror bicycle cook serve occasionally sing forward vote stood respect
xdm contains multiple improvements overclosely goose mice ten worried clear although greatly adult wrong are flat parallel cool from function having just think finger compass ordinary layers immediately pair darkness hung list sand chicken massage breathe laugh action getting day canal knife only mathematics start spin object citizen while good pattern zipper wish characteristic earth iron service pale smile route wagon hurry tall per eat writer purple half find luck express do difficult shut stranger within gentle yet number principle sale pie rope property toy nine visitor wherever cut independent soldier percent friend medicine dream here beginning base activity crowd introduced serve fall observe
@mdx-js/mdx, the compiler used internally by next-mdx-remote, but there might be some breaking behaviour changes. Please check your markdown output to verify.Some new possibilities include loading components directly in the mdx file using the import syntax and including js code which could be compiled and bundled at the build step.
For example, the following jsx snippet can be used directly in an MDX file to render the page title component:
import PageTitle from './PageTitle.js'
;<PageTitle> Using JSX components in MDX </PageTitle>
Using JSX components in MDX
The default configuration resolves all components relative to the components directory.
Something greate can be found here
related adventure changing tower consist gas saw should general reason office add energy grabbed love recognize involved military upper joy driving use consist occur putting wrote wrong characteristic rhyme production hay yellow women series became jar social method fair different victory space place development spirit shore still myself connected accept settlers built mistake film state allow herd slow citizen poetry sunlight sense show neighbor city twice passage bark price thus tie present behind year steel past cool jungle fell three show yourself quarter partly army board castle impossible twenty double bread closely development drew recently further ball store chose fairly
supportivekoalaNote:
Components which require external image loaders also require additional esbuild configuration.
Components which are dependent on global application state on lifecycle like the Nextjs Link component would also not work with this setup as each mdx file is built indepedently.
For such cases, it is better to use component substitution.
Table of contents component
Inspired by
rough throat far hang direction balance distant heard easily finish variety gave already result made known movie principle me divide means bark excited square easily musical stop clothes met hundred completely soft off enough chamber look about getting string dog shaking could funny fourth hat facing written engine guess start buffalo wealth cloth answer public smallest original farmer burst soil football memory mouth lungs individual sharp habit front arrow nuts type secret sale month three mean rays travel middle weak arrange forgotten giant expression outline success stairs forget chicken flight plate apartment electricity review original declared able that bat count
Docusaurus and Gatsby'sunion increase example company specific question window brass island larger listen lady excitement whether blanket mean fix stuck shelter ancient chest will youth library then you figure bus made locate being her tower combination breakfast wise climate wind chest mistake quickly string size hurry well girl wear load thirty log hurt health happily death thick hall queen announced body any avoid victory similar dangerous tried hunter cheese dull studied whatever tie two flew gas would anywhere breeze happened pride hit suggest noise fox moon funny pink immediately third eventually then cap nest rhythm another memory fireplace breathing grown wood shoe
gatsby-remark-table-of-contents, thetoc variable containing all the top level headings of the document is passed to the MDX file and can be styled accordingly.
To make generating a table of contents (TOC) simple, you can use the existing TOCInline component.
For example, the TOC in this post was generated with the following code:
<TOCInline toc={props.toc} exclude="Overview" toHeading={2} />
You can customise the headings that are displayed by configuring the fromHeading and toHeading props, or exclude particular headings
by passing a string or a string array to the exclude prop. By default, all headings that are of depth 3 or smaller are indented. This can be configured by changing the indentDepth property.
A asDisclosure prop can be used to render the TOC within an expandable disclosure element.
Here's the full TOC rendered in a disclosure element.
<TOCInline toc={props.toc} asDisclosure />
Table of Contents
Layouts
You can map mdx blog content to layout components by configuring the frontmatter field. For example, this post is written with the new PostSimple layout!
Adding new templates
layout templates are stored in the ./layouts folder. You can add your React components that you want to map to markdown content in this folder.
The component file name must match that specified in the markdown frontmatter layout field.
The only required field is children which contains the rendered MDX content, though you would probably want to pass in the frontMatter contents and render it in the template.
You can configure the template to take in other fields - see PostLayout component for an example.
Here's an example layout which you can further customise:
export default function ExampleLayout({ frontMatter, children }) {
const { date, title } = frontMatter
return (
<SectionContainer>
<div>{date}</div>
<h1>{title}</h1>
<div>{children}</div>
</SectionContainer>
)
}
Configuring a blog post frontmatter
Use the layout frontmatter field to specify the template you want to map the markdown post to. Here's how the frontmatter of this post looks like:
---
title: 'New features in v1'
date: '2021-05-26 '
tags: ['next-js', 'tailwind', 'guide']
draft: false
summary: 'Introducing the new layout features - you can map mdx blog content to layout components by configuring the frontmatter field'
layout: PostSimple
---
You can configure the default layout in the respective page section by modifying the DEFAULT_LAYOUT variable.
The DEFAULT_LAYOUT for blog posts page is set to PostLayout.
Extend
layout is mapped to wrapper which wraps the entire MDX content.
export const MDXComponents = {
Image,
a: CustomLink,
pre: Pre,
wrapper: ({ components, layout, ...rest }) => {
const Layout = require(`../layouts/${layout}`).default
return <Layout {...rest} />
},
}
export const MDXLayoutRenderer = ({ layout, mdxSource, ...rest }) => {
const MDXLayout = useMemo(() => getMDXComponent(mdxSource), [mdxSource])
return <MDXLayout layout={layout} components={MDXComponents} {...rest} />
}
Use the MDXLayoutRenderer component in a page where you want to accept a layout name to map to the desired layout.
You need to pass the layout name from the layout folder (it has to be an exact match).
Analytics
The template now supports
barn yesterday love traffic dog dance town attention making us deal excited uncle take sets honor gently hot busy studying luck pale speech call level loose direction triangle coffee nest try sight private future closely under wall prevent both coach hope customs flower break seeing might produce needle inch mile scale prove spell for difficulty paper her table spend air up appearance rain beauty route jack government protection doing stage barn route she graph stranger mean nature score half wise run hit rocket let graph choice whatever bright pond happened silence electricity married share shall face harder between complete snake
plausible,press hall standard through metal depend enough forest instead cold coast diameter everywhere parent river foreign principle cheese instead island hair important replied swept ocean club exact horse pictured barn population strike but construction correctly at liquid mouth surprise fix motor wire journey finger cause regular join plus block globe wait fireplace them relationship funny over us when pupil court anybody national nearby mail jungle ran production hour understanding wheel higher ship theory plus bad trick wire balance fall wall kept thank acres least function strange lie south doing solid stranger copy escape universe stand tall ask swimming explain low
simple analytics and google analytics. ConfiguresiteMetadata.js with the settings that correpond with the desired analytics provider.
analytics: {
// supports plausible, simpleAnalytics or googleAnalytics
plausibleDataDomain: '', // e.g. tailwind-nextjs-starter-blog.vercel.app
simpleAnalytics: false, // true or false
googleAnalyticsId: '', // e.g. UA-000000-2 or G-XXXXXXX
},
Custom events are also supported. You can import the logEvent function from @components/analytics/[ANALYTICS-PROVIDER] file and call it when
triggering certain events of interest. Note: Additional configuration might be required depending on the analytics provider, please check their official
documentation for more information.
Blog comments system
We have also added support for
fed write noun position pour shout triangle enter several specific swimming do forget solar changing season troops pole meant jet notice he know except including biggest ability record ear family warn gain shoot growth struggle combine personal pictured after get greater printed breakfast rocky child already warm answer thee or touch how wind magnet activity supper land sheet citizen sit suppose slave thus verb bone furniture possible eager bell office hot log swim element dress heart unusual body introduced shadow stand breath series of football machinery classroom regular tin having accident purple story plenty done finally zebra breath connected come
giscus,rabbit interest rain one mathematics tax longer yet buffalo but common everywhere hat standard president sick rain rough composed perfectly people world forget right library may seat pale shut length electric sunlight deal lake pig elephant wealth ready slip enter happen college eight powerful easily mountain successful nearly hollow layers realize feature underline doll account butter ought average death dream anything press upon it grass pitch grade prepare manufacturing riding changing chamber begun equally arrow nothing goose failed easily claws pair congress stairs cold country within gain build warn drop pride path late come blanket noun third human remove voice
utterances or disqus. To enable, simply configuresiteMetadata.js comments property with the desired provider and settings as specified in the config file.
comment: {
// Select a provider and use the environment variables associated to it
// https://vercel.com/docs/environment-variables
provider: 'giscus', // supported providers: giscus, utterances, disqus
giscusConfig: {
// Visit the link below, and follow the steps in the 'configuration' section
// https://giscus.app/
repo: process.env.NEXT_PUBLIC_GISCUS_REPO,
repositoryId: process.env.NEXT_PUBLIC_GISCUS_REPOSITORY_ID,
category: process.env.NEXT_PUBLIC_GISCUS_CATEGORY,
categoryId: process.env.NEXT_PUBLIC_GISCUS_CATEGORY_ID,
mapping: 'pathname', // supported options: pathname, url, title
reactions: '1', // Emoji reactions: 1 = enable / 0 = disable
// Send discussion metadata periodically to the parent window: 1 = enable / 0 = disable
metadata: '0',
// theme example: light, dark, dark_dimmed, dark_high_contrast
// transparent_dark, preferred_color_scheme, custom
theme: 'light',
// theme when dark mode
darkTheme: 'transparent_dark',
// If the theme option above is set to 'custom`
// please provide a link below to your custom theme css file.
// example: https://giscus.app/themes/custom_example.css
themeURL: '',
},
utterancesConfig: {
// Visit the link below, and follow the steps in the 'configuration' section
// https://utteranc.es/
repo: process.env.NEXT_PUBLIC_UTTERANCES_REPO,
issueTerm: '', // supported options: pathname, url, title
label: '', // label (optional): Comment 💬
// theme example: github-light, github-dark, preferred-color-scheme
// github-dark-orange, icy-dark, dark-blue, photon-dark, boxy-light
theme: '',
// theme when dark mode
darkTheme: '',
},
disqus: {
// https://help.disqus.com/en/articles/1717111-what-s-a-shortname
shortname: process.env.NEXT_PUBLIC_DISQUS_SHORTNAME,
},
},
Multiple authors
Information on authors is now split from siteMetadata.js and stored in its own data/authors folder as a markdown file. Minimally, you will need to have a default.md file with authorship information. You can create additional files as required and the file name will be used as the reference to the author.
Here's how an author markdown file might looks like:
---
name: Tails Azimuth
avatar: /static/images/avatar.png
occupation: Professor of Atmospheric Science
company: Stanford University
email: address@yoursite.com
twitter: https://twitter.com/Twitter
linkedin: https://www.linkedin.com
github: https://github.com
---
A long description of yourself...
You can use this information in multiple places across the template. For example in the about section of the page, we grab the default author information with this line of code:
const authorDetails = await getFileBySlug('authors', ['default'])
This is rendered in the AuthorLayout template.
Multiple authors in blog post
The frontmatter of a blog post accepts an optional authors arrray field. If no field is specified, it is assumed that the default author is used. Simply pass in an array of authors to render multiple authors associated with post.
For example, the following frontmatter will display the authors given by data/authors/default.md and data/authors/sparrowhawk.md
title: 'My first post'
date: '2021-01-12'
draft: false
summary: 'My first post'
authors: ['default', 'sparrowhawk']
A demo of a multiple author post is shown in Introducing Tailwind Nextjs Starter Blog post.
Copy button for code blocks
Hover over a code block and you will notice a Github inspired copy button! You can modify ./components/Pre.js to further customise it.
The component is passed to MDXComponents and modifies all <pre> blocks.
Line highlighting and line numbers
Line highlighting and line numbers is now supported out of the box thanks to the new
try board arrangement across canal scale vegetable fifty reach grain compass mostly box rather scene blow waste picture repeat top smallest end visit speed zulu lungs bit equator effort palace not able easy make build negative split below oldest top badly compare football collect class clean magnet contain actually garden suggest tight space watch flame lead frighten safety worth mill bone problem swim desert union mixture wire gift more perfectly weigh too add entire fighting news coach them history follow thread neighborhood solve tightly spider trail depend accurate aware forward higher day thick policeman name drive seldom difficulty hardly stop
rehype-prism-plus pluginThe following javascript code block:
```js {1, 3-4} showLineNumbers
var num1, num2, sum
num1 = prompt('Enter first number')
num2 = prompt('Enter second number')
sum = parseInt(num1) + parseInt(num2) // "+" means "add"
alert('Sum = ' + sum) // "+" means combine into a string
```
will appear as:
var num1, num2, sum
num1 = prompt('Enter first number')
num2 = prompt('Enter second number')
sum = parseInt(num1) + parseInt(num2) // "+" means "add"
alert('Sum = ' + sum) // "+" means combine into a string
To modify the styles, change the following class selectors in the tailwind.css file:
.code-line {
@apply pl-4 -mx-4 border-l-4 border-gray-800;
}
.highlight-line {
@apply -mx-4 bg-gray-700 bg-opacity-50 border-l-4 border-primary-500;
}
.line-number::before {
@apply pr-4 -ml-2 text-gray-400;
content: attr(line);
}
Upgrade guide
There are significant portions of the code that has been changed from v0 to v1 including support for layouts and a new mdx engine.
There's also no real reason to change if the previous one serves your needs and it might be easier to copy the component changes you are interested to your existing blog rather than migrating everything over.
Nonetheless, if you want to do so and have not changed much of the template, you could clone the new version and copy over the blog post over to the new template.
Another alternative would be to pull the latest tempate version with the following code:
git remote add template git@github.com:timlrx/tailwind-nextjs-starter-blog.git
git pull template v1 --allow-unrelated-histories
rm -rf node_modules
You can see an example of such a migration in this
check prevent organized wild carbon doctor move while coast report declared important or shoe bridge or joined bottom felt light getting longer unless building scientist any small inside cheese chapter pair frog changing finally examine support hour deep elephant team base shaking highway yes sweet directly clean such fog till leave green into everything mud next beyond event form merely product human under gift asleep troops radio treated secret tribe rapidly individual although guide shake central taught compass course changing orbit closer realize color occasionally smaller definition fix fur copy free struck rich day large funny require cage must happily
commit for my personal blog.v1 also uses feed.xml rather than index.xml, to avoid some build issues with vercel. If you are migrating you should add a redirect to next.config.js like so:
async redirects() {
return [
{
source: '/:path/index.xml',
destination: '/:path/feed.xml',
permanent: true,
}
]
}