Yenly Ma

Foamy NextJS Starter

I built a basic starter template for creating a digital garden to share my Today I Learned notes.

It combines Jani Eväkallio's Foam with an example NextJS with MDX repo for low friction set up, easy to add custom styling and deploy to Vercel.

Inspirations

  • note-taking using VS Code with bi-directional linking and a nifty graph view displaying connected notes
  • content focus: Josh Branchaud's TIL GitHub repo
  • learning in public
  • an excuse to build something with NextJS

Github Repo: Foamy NextJS Starter

Challenges

  1. markdown notes in pages directory mixes with other types of files
    • difficult to parse for backlinking
    • lack of frontmatter support makes it difficult to auto-generate backlinks
  2. use of next/image component requires creating custom tag instead of overriding mdx <img> because each <img> is wrapped in <p> and next/image renders a <div>
    • workaround is to create a custom mdx tag pointing to custom Image component that uses next/image component
    • try using remark-unwrap-images to filter out wrapping <p>

Progress

  • Added support for responsive images using next/image component in markdown content
import Image from '../components/Image'
const mdComponents = {
a: props => <AnchorTag {...props} />,
code: CodeBlock,
img: (props) => <div className="nextImageWrapper"><Image {...props} /></div>,
Image: (props) => <div className="nextImageWrapper"><Image {...props} /></div>
}
  • Using remark-unwrap-images allows img to map to my custom <Image /> component without triggering dom nesting warning.
  • Allows use of markdown image syntax to render default next/image component options using query strings to provide width and height.
![Excalidrawn PNG](/images/excalidrawn.png?600x460)
  • Allows using custom <Image /> in markdown to enable more next/mage component options
<Image src="/images/excalidrawn.png" alt="Excalidrawn PNG" height="460" width="600" layout="responsive" />

Pondering: Why not auto pass all props from <Image /> to next/image component enabling full options support?