2021 - Next.js Build Notes
These notes start from the point when I moved off mdx-bundler and onto next-mdx-remote. I started from scratch.
Initial setup
mkdir alanwsmith.com
cd alanwsmith.com
npx create-next-app .
npm i next-mdx-remote gray-matter
npm i @netlify/plugin-nextjs
That got everything ready to go based off the work done on https://next-mdx-remote-blog-example.netlify.app/
Moved all components into their own files since next-mdx-remote doesn't work with them inside of files.
The data has to be added directly in the component as well, like this:
<Checklist data={`
Start Monster Cat Audio
Set Monster Cat Audio to Shuffle
Mute headphones
Switch OBS to main scene and check that music and vocals are working
`} />
Installed Tailwind from these instructions: via: https://tailwindcss.com/docs/guides/nextjs
Starting with
npm install -D tailwindcss@latest postcss@latest autoprefixer@latest
Then ran this
npx tailwindcss init -p
which created tailwind.config.js
and `postcss.config.js`
The next step was to put this in `tailwind.config.js`
purge: ['./pages/**/*.{js,ts,jsx,tsx}', './components/**/*.{js,ts,jsx,tsx}'],
Then replaced the contents of ./styles/global.css with:
@ @ @
That gets the basic framework in place.
Setup to use a basic LayoutMain file that has tailwind in it:
file: ./components/LayoutMain.js
Then updated the index.js and [slug].js file to use it with:
file: ./pages/index.js
file: ./pages/posts/[slug].js
const CONTENT_DIR = path.
Installed prismjs with:
npm i prismjs
Added import 'prismjs/themes/prism-tomorrow.css'
to _app.js so it looks like this:
And then updated ./components/LayoutMain.js so it looks like this:
const prism =
That gets the syntax highlighting in place so that code fences like:
const someThing = 'An example'
Render as:
const someThing = 'An example'
Added in favicons and header stuff and nav. see the github for details.
Using next/image requires importing the images directly to get the benefits of local functionality. Unfortunately next-mdx-remote doesn't handle that. So, I ended up created a components/Img.js
file with:
const imgMap =
That gets included in the [slug].js
file with the other components (via: `import Img from '../../components/Img'`) and passed to MDXRemote
like this:
<MDXRemote
components= }
/>
Then, for every image that's going to be called I create an import like:
and a reference in a mapping object so I can access it like this:
const imgMap =
I make sure the image filenames work as variable names so I can keep the same name in place across the board.
Then, to use the image, I call it like this in the MDX source files:
I build the Img.js
file with a script before I publish that grabs all the images in the _images
directory and makes an entry for each one. That way, all I need to do is drop in an image with a valid name and then use it in the <Img>
tag. The rest of the work is automated.
I'd prefer to keep the images in sub-directories by year but that's more than I want to tackle at the moment. Getting the images in place in generally was the key. I can optimize later if that becomes necessary.
Something that's cool about this is that it will let me customize image calls further if I want since there's a layer of abstraction between the content and the <Image>
call. For example, instead of just sending a style tag I could send an attribute that adds extra divs and puts in captions, etc... In fact, now that I think about it, that's exactly what I'm going to do.
It's a bit of a hack, but it works.
TODO: Figure out if this impacts the performance of the site as the number of images goes up since they are all being imported.