diff --git a/apps/web/app/docs/[[...slug]]/preview-implementation.tsx b/apps/web/app/docs/[[...slug]]/preview-implementation.tsx
index 8470002c..6b2e1f4e 100644
--- a/apps/web/app/docs/[[...slug]]/preview-implementation.tsx
+++ b/apps/web/app/docs/[[...slug]]/preview-implementation.tsx
@@ -4,6 +4,7 @@ import { z } from "zod"
import { Demo } from "@/components/demo"
import { Pre, RawCode, highlight } from "codehike/code"
import { CopyButton } from "@/components/copy-button"
+import { ComponentPackLink } from "@/components/component-pack-link"
const ContentSchema = Block.extend({
demo: Block,
diff --git a/apps/web/components/component-pack-link.tsx b/apps/web/components/component-pack-link.tsx
new file mode 100644
index 00000000..8fc9c079
--- /dev/null
+++ b/apps/web/components/component-pack-link.tsx
@@ -0,0 +1,20 @@
+import { ArrowRight } from "lucide-react"
+
+export function ComponentPackLink() {
+ return (
+
+ Don't have time to build it yourself? Get a documentation component
+ library customized for your tech stack and design system.
+
+
+ )
+}
diff --git a/apps/web/content/blog/content-presentation-gap.mdx b/apps/web/content/blog/content-presentation-gap.mdx
index 3825b88a..5ee054f8 100644
--- a/apps/web/content/blog/content-presentation-gap.mdx
+++ b/apps/web/content/blog/content-presentation-gap.mdx
@@ -6,9 +6,13 @@ authors: [pomber]
draft: true
---
+import { Demo } from "./content-presentation-gap"
+
+Notice: content means Markdown, presentation means UI components. So, another title could be "The Markdown-React gap".
+
Let's tart with an example.
-> demo (roman emperors)
+
This is a UI pattern commonly referred as scrollytelling, where the content is presented in a way that is tightly coupled with the user's scroll position.
@@ -19,6 +23,8 @@ It's also used for technical content like [Stripe's API reference](https://strip
A component to implement this pattern is not super hard to build, usually it's a combination of an intersection observer and position sticky.
```tsx
+import { useEffect, useRef, useState } from "react"
+
type Props = {
steps: {
content: React.ReactNode
diff --git a/apps/web/content/blog/content-presentation-gap.tsx b/apps/web/content/blog/content-presentation-gap.tsx
new file mode 100644
index 00000000..08bf5ef0
--- /dev/null
+++ b/apps/web/content/blog/content-presentation-gap.tsx
@@ -0,0 +1,100 @@
+"use client"
+
+import { useEffect, useRef, useState } from "react"
+
+export function Demo() {
+ return (
+
+
+
Augustus
+
+ Augustus was the first Roman emperor, reigning from 27 BC
+ until his death in AD 14.
+
+
+ ),
+ sticker: (
+
+ ),
+ },
+ {
+ content: (
+
+
Nero
+
+ Nero was the last Roman emperor of the Julio-Claudian dynasty.
+
+ )
+}
diff --git a/apps/web/content/blog/the-curse-of-markdown.mdx b/apps/web/content/blog/the-curse-of-markdown.mdx
index 93efe7f8..1fde2a96 100644
--- a/apps/web/content/blog/the-curse-of-markdown.mdx
+++ b/apps/web/content/blog/the-curse-of-markdown.mdx
@@ -25,8 +25,8 @@ Tradeoffs: https://youtu.be/zqhE-CepH2g?si=7iYgDUjAhJNVmYJN&t=446
examples of websites that mdx allow:
-- josh's blog
-- react docs
+- interactive blogs
+- interactive docs
---
@@ -36,5 +36,3 @@ Examples are:
- stripe
- swiftui
-- nanda
-- pudding
diff --git a/apps/web/content/docs/api.mdx b/apps/web/content/docs/api.mdx
new file mode 100644
index 00000000..24de8438
--- /dev/null
+++ b/apps/web/content/docs/api.mdx
@@ -0,0 +1,213 @@
+---
+title: API Reference
+description: Comprehensive list of codehike's API
+---
+
+import { Usage } from "./api"
+
+## `codehike/mdx`
+
+```tsx
+import { remarkCodeHike, recmaCodeHike } from "codehike/mdx"
+```
+
+### `remarkCodeHike`
+
+A remark plugin that transform codeblocks and inline code into the specified components.
+
+- from annotation
+- you have to provide the components
+
+```tsx
+import { remarkCodeHike, recmaCodeHike } from "codehike/mdx"
+
+/** @type {import('codehike/mdx').CodeHikeConfig} */
+const chConfig = {
+ components: { code: "MyCode", inlineCode: "MyInlineCode" },
+ ignoreCode: (codeblock) => codeblock.lang === "mermaid",
+ syntaxHighlighting: { theme: "github-dark" },
+}
+
+// what you do with the `mdxOptions` depends on what you use to handle mdx
+const mdxOptions = {
+ remarkPlugins: [[remarkCodeHike, chConfig], ...otherRemarkPlugins],
+ recmaPlugins: [[recmaCodeHike, chConfig]],
+}
+```
+
+#### `CodeHikeConfig.components.code`
+
+If you specify a component for `code`, the `remarkCodeHike` plugin will replace code blocks with that component. The language, meta, and value of the code block will be passed inside a `codeblock` prop.
+
+
+
+## !caption
+
+How `remarkCodeHike` compiles codeblocks using the `code` component
+
+## !left
+
+```tsx your-config.js
+const chConfig = {
+ // !mark[/MyCode/] 1
+ components: { code: "MyCode" },
+}
+```
+
+{/* prettier-ignore */}
+````mdx content.mdx
+# Hello
+
+{/* !mark[/js|lorem ipsum|console.log\(1\)/gm] 5 */}
+```js lorem ipsum
+console.log(1)
+```
+````
+
+## !right
+
+{/* prettier-ignore */}
+```jsx compiled output -w
+export default function Content(props = {}) {
+ // !mark[/MyCode/gm] 1
+ // !mark[/js|lorem ipsum|console.log\(1\)/gm] 5
+ const { MyCode } = props.components
+ return (
+ <>
+
Hello
+
+ >
+ )
+}
+```
+
+
+
+FAQ
+
+- how to pass the components to the `Content` component?
+- how to syntax highlight the code?
+
+#### `CodeHikeConfig.components.inlineCode`
+
+If you specify a component for `inlineCode`, the `remarkCodeHike` plugin will replace inline code with that component. The value of the inline code will be passed inside a `codeblock` prop.
+
+Code Hike uses a special syntax to define inline code ``_`code`_``. This syntax also allows you to specify the language and meta for inline code ``_py lorem ipsum`print 5`_``, will give you _`{lang: "py", meta: "lorem ipsum", value: "print 5"}`_.
+
+
+
+## !caption
+
+How `remarkCodeHike` compiles inline code using the `inlineCode` component
+
+## !left
+
+```tsx your-config.js
+const chConfig = {
+ // !mark[/MyInlineCode/] 1
+ components: { inlineCode: "MyInlineCode" },
+}
+```
+
+{/* prettier-ignore */}
+````mdx content.mdx -w
+# Hello
+
+Case 1: `var x = 10`
+
+Case 2: _`var x = 10`_
+
+Case 3: _css`a { color: #123 }`_
+````
+
+## !right
+
+{/* prettier-ignore */}
+```jsx compiled output -w
+export default function Content(props = {}) {
+ // !mark[/MyInlineCode/gm] 1
+ const { MyInlineCode } = props.components
+ return (
+ <>
+