--- id: math-equations title: Math Equations description: Writing LaTeX Math Equations slug: /markdown-features/math-equations --- import BrowserWindow from '@site/src/components/BrowserWindow'; Mathematical equations can be rendered using [KaTeX](https://katex.org). ## Usage Please read [KaTeX](https://katex.org) documentation for more details. ### Inline Write inline math equations by wrapping LaTeX equations between `$`: ```mdx Let $f:[a,b] \to \R$ be Riemann integrable. Let $F:[a,b]\to\R$ be $F(x)= \int_{a}^{x}f(t)dt$. Then $$F$$ is continuous, and at all $x$ such that $f$ is continuous at $x$, $F$ is differentiable at $x$ with $F'(x)=f(x)$. ``` Let $f:[a,b] \to \R$ be Riemann integrable. Let $F:[a,b]\to\R$ be $F(x)= \int_{a}^{x}f(t)dt$. Then $F$ is continuous, and at all $x$ such that $f$ is continuous at $x$, $F$ is differentiable at $x$ with $F'(x)=f(x)$. ### Blocks For equation block or display mode, use line breaks and `$$`: ```mdx $$ I = \int_0^{2\pi} \sin(x) dx $$ ``` $$ I = \int_0^{2\pi} \sin(x) dx $$ ## Configuration To enable KaTeX, you need to install `remark-math` and `rehype-katex` plugins. ```bash npm2yarn npm install --save remark-math@3 rehype-katex@5 hast-util-is-element@1.1.0 ``` :::caution Use the exact same versions. The latest versions are incompatible with Docusaurus 2. ::: Import the plugins in `docusaurus.config.js`: ```js const math = require('remark-math'); const katex = require('rehype-katex'); ``` Add them to your content plugin or preset options (usually `@docusaurus/preset-classic` docs options): ```js remarkPlugins: [math], rehypePlugins: [katex], ``` Include the KaTeX CSS in your config under `stylesheets`: ```js stylesheets: [ { href: 'https://cdn.jsdelivr.net/npm/katex@0.13.24/dist/katex.min.css', type: 'text/css', integrity: 'sha384-odtC+0UGzzFL/6PNoE8rX/SPcQDXBJ+uRepguP4QkPCm2LBxH3FA3y+fKSiJ+AmM', crossorigin: 'anonymous', }, ], ``` Overall the changes look like: ```js title="docusaurus.config.js" // highlight-start const math = require('remark-math'); const katex = require('rehype-katex'); // highlight-end module.exports = { title: 'Docusaurus', tagline: 'Build optimized websites quickly, focus on your content', presets: [ [ '@docusaurus/preset-classic', { docs: { path: 'docs', // highlight-start remarkPlugins: [math], rehypePlugins: [katex], // highlight-end }, }, ], ], // highlight-start stylesheets: [ { href: 'https://cdn.jsdelivr.net/npm/katex@0.13.24/dist/katex.min.css', type: 'text/css', integrity: 'sha384-odtC+0UGzzFL/6PNoE8rX/SPcQDXBJ+uRepguP4QkPCm2LBxH3FA3y+fKSiJ+AmM', crossorigin: 'anonymous', }, ], // highlight-end }; ``` ## Upgrading rehype-katex beyond recommended version :::tip Only use the latest version if you actually need the bleeding-edge features of $\KaTeX$. Most users should find the older versions work just as well. ::: The latest versions of `rehype-katex` (starting from `v6.0.0`) has moved to ES Modules, a new module system of JavaScript, which Docusaurus doesn't officially support yet. However, it is possible to import `rehype-katex` dynamically, using an async config creator. Docusaurus will call this creator function and wait for it to return the config object. ```js title="docusaurus.config.js" async function createConfig() { // ES Modules are imported with `import()` instead of `require()`, and are imported asynchronously // highlight-next-line const katex = (await import('rehype-katex')).default; return { // ... }; } ``` In this case, the overall configuration changes will look like: ```js title="docusaurus.config.js" // highlight-next-line const math = require('remark-math'); async function createConfig() { // highlight-next-line const katex = (await import('rehype-katex')).default; return { title: 'Docusaurus', tagline: 'Build optimized websites quickly, focus on your content', presets: [ [ '@docusaurus/preset-classic', { docs: { path: 'docs', // highlight-start remarkPlugins: [math], rehypePlugins: [katex], // highlight-end }, }, ], ], // highlight-start stylesheets: [ { href: 'https://cdn.jsdelivr.net/npm/katex@0.15.2/dist/katex.min.css', type: 'text/css', integrity: 'sha384-MlJdn/WNKDGXveldHDdyRP1R4CTHr3FeuDNfhsLPYrq2t0UBkUdK2jyTnXPEK1NQ', crossorigin: 'anonymous', }, ], // highlight-end }; } module.exports = createConfig; ```