Next Theme Starter
A sample Next.js (v13) project for getting started with Theme UI, MDX (v2), & TypeScript.
Usage
- Import this repo to your coding environment of choice. Download a zip, use Create Next App (
yarn create next-app -e https://github.com/lachlanjc/next-theme-starter
), or use the GitHub import on CodeSandbox/repl.it/Glitch/etc. pnpm
to install dependencies.pnpm dev
to start your server.- Start adding your own pages & components in their respective directories.
Configuration
Theme switcher
There’s an included example theme switcher component at components/color-switcher.tsx
,
which is included on every page through its inclusion in pages/_app.tsx
.
Feel free to change/remove it.
Custom theme
By default, a theme inspired by the Hack Club Theme is included.
To edit the theme, head to lib/theme.ts
.
Running at another port
Super easy: pnpm dev -p 5000
Dependency updates
The included Dependabot configuration file means you’ll automatically get PRs
every Monday with dependency updates. Delete .github/dependabot.yml
to
disable.
Meta tags
This template includes a Meta
component for adding full meta tags.
To set the defaults, open components/meta.tsx
& change the default props.
It’s included in pages/_app.tsx
so all pages have the default tags without
anything per-page, but due to the key
s included on each tag, if you render
the component multiple times (such as once in _app
& again on an invidual page),
the last instance of each tag will be used, with duplicates.
If you don’t set a description
or image
, the relevant tags for those fields
will be omitted.
Here’s how you use Meta
on a page:
import Meta from '../components/meta'
const AboutPage = () => (
<>
<Meta
title="About" // page title
description="About our nonprofit." // page description
image="https://yourdomain.com/special-card.png" // large summary card image URL
/>
{/* … */}
</>
)
export default AboutPage
(The default props are included on the component instead of _app.tsx
so you
don’t have to re-include all the props on each page.)
You can also pass children to Meta
to quickly include custom tags inside the
Next.js Head
.
Icons
No iconsets are included with this starter, but a few I recommend:
Adding analytics
I recommend Fathom Analytics or Plausible.io for simple, privacy-focused analytics.
Example _app.tsx
with Fathom (requires fathom-client
)
import React, { useEffect } from 'react'
import type { AppProps } from 'next/app'
import { useRouter } from 'next/router'
import Head from 'next/head'
import Meta from '#/components/meta'
import theme from '#/lib/theme'
import { ThemeProvider } from 'theme-ui'
import * as Fathom from 'fathom-client'
const App = ({ Component, pageProps }: AppProps) => {
const router = useRouter()
useEffect(() => {
Fathom.load('YOURCODE', {
includedDomains: ['YOURDOMAIN.com'],
url: 'https://YOURSUB.YOURDOMAIN.com/script.js', // optional
})
const onRouteChangeComplete = () => Fathom.trackPageview()
router.events.on('routeChangeComplete', onRouteChangeComplete)
return () => {
router.events.off('routeChangeComplete', onRouteChangeComplete)
}
}, [])
return (
<ThemeProvider theme={theme}>
<Meta />
<Component {...pageProps} />
</ThemeProvider>
)
}
export default App
Example _app.tsx
with Plausible (requires next-plausible
)
import React from 'react'
import type { AppProps } from 'next/app'
import Head from 'next/head'
import PlausibleProvider from 'next-plausible'
import theme from '#/lib/theme'
import { ThemeProvider } from 'theme-ui'
import Meta from '#/components/meta'
const App = ({ Component, pageProps }: AppProps) => {
return (
<PlausibleProvider domain="YOURDOMAIN.com">
<ThemeProvider theme={theme}>
<Meta />
<Component {...pageProps} />
</ThemeProvider>
</PlausibleProvider>
)
}
export default App
Deployment
I highly recommend using Vercel for deployment. It requires no configuration, is totally free for personal projects, and supports all the features of Next.js with the best performance. Refer to their documentation for more details.
Alternatively, you can deploy your site on Netlify (also free); Netlify’s documentation is here.