Framework Integration
Complete integration guides for using remark-notes-plugin
with popular frameworks and static site generators.
Next.js
Next.js 13+ (App Router with MDX)
For Next.js 13+ using the App Router with @next/mdx
:
1. Install dependencies:
npm install remark-notes-plugin @next/mdx @mdx-js/loader @mdx-js/react
2. Configure next.config.mjs
:
import createMDX from '@next/mdx';
import remarkNotes from 'remark-notes-plugin';
/** @type {import('next').NextConfig} */
const nextConfig = {
pageExtensions: ['js', 'jsx', 'md', 'mdx', 'ts', 'tsx'],
};
const withMDX = createMDX({
options: {
remarkPlugins: [remarkNotes],
rehypePlugins: [],
},
});
export default withMDX(nextConfig);
3. Import styles in your root layout (app/layout.tsx
):
import 'remark-notes-plugin/styles.css';
import './globals.css';
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<html lang="en">
<body>{children}</body>
</html>
);
}
4. Create an MDX file (app/blog/post.mdx
):
# My Blog Post
> [!tip]
> This is a helpful tip in Next.js!
Regular content here...
> [!important]
> Don't forget this important detail.
Next.js (Pages Router with MDX)
For the traditional Pages Router:
1. Install dependencies:
npm install remark-notes-plugin @next/mdx @mdx-js/loader
2. Configure next.config.js
:
const withMDX = require('@next/mdx')({
extension: /\.mdx?$/,
options: {
remarkPlugins: [require('remark-notes-plugin')],
rehypePlugins: [],
},
});
module.exports = withMDX({
pageExtensions: ['js', 'jsx', 'ts', 'tsx', 'md', 'mdx'],
});
3. Import styles in pages/_app.js
or pages/_app.tsx
:
import 'remark-notes-plugin/styles.css';
import '../styles/globals.css';
export default function App({ Component, pageProps }) {
return <Component {...pageProps} />;
}
Next.js with Custom Markdown Processing
If you're processing markdown programmatically:
import { unified } from 'unified';
import remarkParse from 'remark-parse';
import remarkNotes from 'remark-notes-plugin';
import remarkRehype from 'remark-rehype';
import rehypeStringify from 'rehype-stringify';
export async function getStaticProps() {
const markdown = `
> [!note]
> This is processed server-side
`;
const result = await unified()
.use(remarkParse)
.use(remarkNotes)
.use(remarkRehype)
.use(rehypeStringify)
.process(markdown);
return {
props: {
content: result.toString(),
},
};
}
tipFor better performance with many pages, disable automatic style injection and import the CSS file manually in your layout.
Astro
Astro has excellent built-in support for remark plugins.
1. Install the plugin:
npm install remark-notes-plugin
2. Configure astro.config.mjs
:
import { defineConfig } from 'astro/config';
import remarkNotes from 'remark-notes-plugin';
export default defineConfig({
markdown: {
remarkPlugins: [remarkNotes],
},
});
3. The CSS is automatically injected, but you can also import it manually:
---
// src/layouts/Layout.astro
import 'remark-notes-plugin/styles.css';
---
<html lang="en">
<head>
<meta charset="utf-8" />
<title>My Site</title>
</head>
<body>
<slot />
</body>
</html>
4. Use in your markdown files:
---
title: My Page
---
# Welcome
> [!note]
> This is a note in Astro!
> [!tip]
> Astro makes it super easy to use remark plugins.
Astro with Custom Class Prefix
import { defineConfig } from 'astro/config';
import remarkNotes from 'remark-notes-plugin';
export default defineConfig({
markdown: {
remarkPlugins: [
[remarkNotes, { classPrefix: 'astro' }]
],
},
});
Gatsby
1. Install dependencies:
npm install remark-notes-plugin gatsby-plugin-mdx
2. Configure gatsby-config.js
:
module.exports = {
plugins: [
{
resolve: 'gatsby-plugin-mdx',
options: {
extensions: ['.mdx', '.md'],
mdxOptions: {
remarkPlugins: [require('remark-notes-plugin')],
},
},
},
],
};
3. Import styles in gatsby-browser.js
:
import 'remark-notes-plugin/styles.css';
4. Or disable auto-injection and use CSS modules:
module.exports = {
plugins: [
{
resolve: 'gatsby-plugin-mdx',
options: {
mdxOptions: {
remarkPlugins: [
[require('remark-notes-plugin'), { injectStyles: false }]
],
},
},
},
],
};
Docusaurus
Docusaurus is what we use for this documentation site!
1. Install the plugin:
npm install remark-notes-plugin
2. Configure docusaurus.config.js
:
import remarkNotes from 'remark-notes-plugin';
const config = {
presets: [
[
'classic',
{
docs: {
remarkPlugins: [remarkNotes],
},
blog: {
remarkPlugins: [remarkNotes],
},
},
],
],
};
export default config;
3. Import styles in src/css/custom.css
:
@import 'remark-notes-plugin/styles.css';
/* Your custom styles below */
noteStyles are automatically injected by default, but importing them manually gives you more control over the cascade order.
VitePress
1. Install dependencies:
npm install remark-notes-plugin
2. Configure .vitepress/config.ts
:
import { defineConfig } from 'vitepress';
import remarkNotes from 'remark-notes-plugin';
export default defineConfig({
markdown: {
config: (md) => {
md.use(remarkNotes);
},
},
});
3. Import styles in .vitepress/theme/index.ts
:
import DefaultTheme from 'vitepress/theme';
import 'remark-notes-plugin/styles.css';
import './custom.css';
export default {
extends: DefaultTheme,
};
importantVitePress uses markdown-it by default, not remark. You may need additional configuration or consider using a different approach for VitePress.
Eleventy (11ty)
1. Install dependencies:
npm install @11ty/eleventy-plugin-remark remark-notes-plugin
2. Configure .eleventy.js
:
const eleventyRemark = require('@11ty/eleventy-plugin-remark');
const remarkNotes = require('remark-notes-plugin');
module.exports = function(eleventyConfig) {
eleventyConfig.addPlugin(eleventyRemark, {
plugins: [remarkNotes],
});
return {
dir: {
input: 'src',
output: 'dist',
},
};
};
Hugo
Hugo doesn't use remark directly, but you can preprocess markdown files:
1. Create a preprocessing script (scripts/process-markdown.js
):
import { unified } from 'unified';
import remarkParse from 'remark-parse';
import remarkNotes from 'remark-notes-plugin';
import remarkStringify from 'remark-stringify';
import { readFileSync, writeFileSync } from 'fs';
import { glob } from 'glob';
async function processFile(filepath) {
const content = readFileSync(filepath, 'utf-8');
const result = await unified()
.use(remarkParse)
.use(remarkNotes, { injectStyles: false })
.use(remarkStringify)
.process(content);
writeFileSync(filepath, result.toString());
}
const files = glob.sync('content/**/*.md');
files.forEach(processFile);
2. Add to your build process in package.json
:
{
"scripts": {
"prebuild": "node scripts/process-markdown.js",
"build": "hugo"
}
}
Vanilla Unified/Remark
For custom implementations using unified directly:
import { unified } from 'unified';
import remarkParse from 'remark-parse';
import remarkNotes from 'remark-notes-plugin';
import remarkRehype from 'remark-rehype';
import rehypeStringify from 'rehype-stringify';
async function processMarkdown(markdown: string) {
const result = await unified()
.use(remarkParse)
.use(remarkNotes, {
classPrefix: 'custom',
injectStyles: false,
})
.use(remarkRehype, { allowDangerousHtml: true })
.use(rehypeStringify, { allowDangerousHtml: true })
.process(markdown);
return result.toString();
}
// Usage
const html = await processMarkdown(`
> [!tip]
> This is processed with vanilla unified!
`);
console.log(html);
Configuration Best Practices
When to Disable Style Injection
Set injectStyles: false
when:
- Using a build tool (Vite, Webpack, Rollup) that handles CSS imports
- Server-Side Rendering with separate CSS extraction
- Custom styling - you're providing your own styles
- Performance optimization - better caching with separate CSS files
When to Use Custom Class Prefix
Use classPrefix
when:
- Avoiding conflicts with existing CSS classes
- Multiple instances of the plugin with different styles
- Framework conventions - matching your project's naming scheme
- Scoped styling - better encapsulation
Troubleshooting
Styles Not Appearing
Problem: Notes appear unstyled.
Solutions:
- Ensure styles are imported:
import 'remark-notes-plugin/styles.css'
- Check if
injectStyles
is set tofalse
and you forgot to import CSS - Verify CSS load order in your build tool
Build Errors with MDX
Problem: Build fails when processing MDX files.
Solutions:
- Ensure you're using compatible versions of MDX and remark
- Check for syntax errors in your markdown notes
- Try setting
injectStyles: false
for SSR environments
TypeScript Errors
Problem: TypeScript can't find module types.
Solution:
// If types aren't recognized, add to your tsconfig.json:
{
"compilerOptions": {
"moduleResolution": "node",
"esModuleInterop": true
}
}
Next Steps
- API Reference - Complete API documentation
- CSS Customization - Customize note styles
- Troubleshooting - Common issues and solutions