Core: Support lucide react icons plugin for loader()

This commit is contained in:
Fuma Nama
2025-10-01 12:03:43 +08:00
parent e19f009dec
commit 747bdbc29d
8 changed files with 58 additions and 14 deletions
+5
View File
@@ -0,0 +1,5 @@
---
'fumadocs-core': patch
---
Support lucide react icons plugin for `loader()`
+7 -9
View File
@@ -1,19 +1,17 @@
import { createMDXSource } from 'fumadocs-mdx/runtime/next';
import type { InferMetaType, InferPageType } from 'fumadocs-core/source';
import { loader } from 'fumadocs-core/source';
import { icons } from 'lucide-react';
import {
type InferMetaType,
type InferPageType,
loader,
} from 'fumadocs-core/source';
import { openapiPlugin } from 'fumadocs-openapi/server';
import { createElement } from 'react';
import { blog as blogPosts, docs } from '@/.source';
import { lucideIconsPlugin } from 'fumadocs-core/source/lucide-icons';
export const source = loader({
baseUrl: '/docs',
icon(icon) {
if (icon && icon in icons)
return createElement(icons[icon as keyof typeof icons]);
},
source: docs.toFumadocsSource(),
plugins: [openapiPlugin()],
plugins: [lucideIconsPlugin(), openapiPlugin()],
});
export const blog = loader({
+10 -1
View File
@@ -60,6 +60,10 @@
"import": "./dist/source/index.js",
"types": "./dist/source/index.d.ts"
},
"./source/*": {
"import": "./dist/source/plugins/*.js",
"types": "./dist/source/plugins/*.d.ts"
},
"./utils/*": {
"import": "./dist/utils/*.js",
"types": "./dist/utils/*.d.ts"
@@ -146,6 +150,7 @@
"@types/react-dom": "^19.1.9",
"algoliasearch": "5.39.0",
"eslint-config-custom": "workspace:*",
"lucide-react": "^0.544.0",
"mdast-util-mdx-jsx": "^3.2.0",
"mdast-util-mdxjs-esm": "^2.0.1",
"next": "^15.5.4",
@@ -168,7 +173,8 @@
"react": "18.x.x || 19.x.x",
"react-dom": "18.x.x || 19.x.x",
"react-router": "7.x.x",
"waku": "^0.26.0"
"waku": "^0.26.0",
"lucide-react": "*"
},
"peerDependenciesMeta": {
"@mixedbread/sdk": {
@@ -200,6 +206,9 @@
},
"@tanstack/react-router": {
"optional": true
},
"lucide-react": {
"optional": true
}
},
"publishConfig": {
@@ -0,0 +1,25 @@
import type { LoaderPlugin } from '@/source';
import { iconPlugin } from '@/source/plugins/icon';
import { icons } from 'lucide-react';
import { createElement } from 'react';
/**
* Convert icon names into Lucide Icons, requires `lucide-react` to be installed.
*/
export function lucideIconsPlugin(
options: {
defaultIcon?: keyof typeof icons;
} = {},
): LoaderPlugin {
const { defaultIcon } = options;
return iconPlugin((icon = defaultIcon) => {
if (icon === undefined) return;
const Icon = icons[icon as keyof typeof icons];
if (!icon) {
console.warn(`[lucide-icons-plugin] Unknown icon detected: ${icon}.`);
return;
}
return createElement(Icon);
});
}
+2 -2
View File
@@ -12,8 +12,8 @@ export default defineConfig({
entry: [
'src/{toc,link,breadcrumb,sidebar,dynamic-link,hide-if-empty}.tsx',
'src/{server,source,mdx-plugins,page-tree}/index.ts',
'src/negotiation/*.ts',
'src/content/*.ts',
'src/{negotiation,content}/*',
'src/source/plugins/lucide-icons.ts',
'src/search/{index,client,server,algolia,orama-cloud}.ts',
'src/utils/use-on-change.ts',
'src/utils/use-effect-event.ts',
+1 -1
View File
@@ -3,7 +3,6 @@
"version": "0.0.0",
"private": true,
"description": "Used to track dependency versions in create-fumadocs-app",
"license": "MIT",
"dependencies": {
"@biomejs/biome": "^2.2.4",
"@content-collections/core": "^0.11.1",
@@ -23,6 +22,7 @@
"@vitejs/plugin-react": "^5.0.3",
"gray-matter": "^4.0.3",
"isbot": "^5.1.31",
"lucide-react": "^0.544.0",
"next": "15.5.4",
"postcss": "^8.5.6",
"react": "^19.1.1",
+6 -1
View File
@@ -233,7 +233,12 @@ async function createNextPackageJson(
}[lint]),
},
dependencies: {
...pick(versionPkg.dependencies, ['next', 'react', 'react-dom']),
...pick(versionPkg.dependencies, [
'next',
'react',
'react-dom',
'lucide-react',
]),
...pick(localVersions, ['fumadocs-ui', 'fumadocs-core']),
...{
'+next+content-collections': {
@@ -1,10 +1,12 @@
import { docs } from '@/.source';
import { type InferPageType, loader } from 'fumadocs-core/source';
import { lucideIconsPlugin } from 'fumadocs-core/source/lucide-icons';
// See https://fumadocs.dev/docs/headless/source-api for more info
export const source = loader({
baseUrl: '/docs',
source: docs.toFumadocsSource(),
plugins: [lucideIconsPlugin()],
});
export function getPageImage(page: InferPageType<typeof source>) {