Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Changed the exemple of dynamic icons using NextJS #1580

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 17 additions & 28 deletions docs/guide/packages/lucide-react.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,10 @@ export default App;

| name | type | default |
| --------------------- | --------- | ------------ |
| `size` | *number* | 24 |
| `color` | *string* | currentColor |
| `strokeWidth` | *number* | 2 |
| `absoluteStrokeWidth` | *boolean* | false |
| `size` | _number_ | 24 |
| `color` | _string_ | currentColor |
| `strokeWidth` | _number_ | 2 |
| `absoluteStrokeWidth` | _boolean_ | false |

### Applying props

Expand Down Expand Up @@ -109,9 +109,10 @@ Example with React suspense:

```tsx
import React, { lazy, Suspense } from 'react';
import { dynamicIconImports, LucideProps } from 'lucide-react';
import { LucideProps } from 'lucide-react';
import dynamicIconImports from 'lucide-react/dynamicIconImports';

const fallback = <div style={{ background: '#ddd', width: 24, height: 24 }}/>
const fallback = <div style={{ background: '#ddd', width: 24, height: 24 }} />;

interface IconProps extends Omit<LucideProps, 'ref'> {
name: keyof typeof dynamicIconImports;
Expand All @@ -125,43 +126,31 @@ const Icon = ({ name, ...props }: IconProps) => {
<LucideIcon {...props} />
</Suspense>
);
}
};

export default Icon
export default Icon;
```

##### NextJS Example

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should make separate sections for the App router and pages router.

Pages router should use the docs like it was before.

And create a new section specially targeting the App Router.
With this code example:

import { LucideProps, icons } from 'lucide-react';

interface IconProps extends LucideProps {
  name: keyof typeof icons;
}

const Icon = ({ name, ...props }: IconProps) => {
  const LucideIcon = icons[name];

  return <LucideIcon {...props} />;
};

export default Icon;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi, so is this the solution for dynamic import with the app router?

In NextJS, [the dynamic function](https://nextjs.org/docs/pages/building-your-application/optimizing/lazy-loading#nextdynamic) can be used to dynamically load the icon component.

To make dynamic imports work with NextJS, you need to add `lucide-react` to the [`transpilePackages`](https://nextjs.org/docs/app/api-reference/next-config-js/transpilePackages) option in your `next.config.js` like this:

```js
/** @type {import('next').NextConfig} */
const nextConfig = {
transpilePackages: ['lucide-react'] // add this
}

module.exports = nextConfig

```
In NextJS [the dynamic function](https://nextjs.org/docs/pages/building-your-application/optimizing/lazy-loading#nextdynamic) can be used to load the icon component dynamically. Do not use dynamicIconImports with NextJS.

You can then start using it:

```tsx
import dynamic from 'next/dynamic'
import { LucideProps } from 'lucide-react';
import dynamicIconImports from 'lucide-react/dynamicIconImports';
import dynamic from 'next/dynamic';
import type Lucide from 'lucide-react';

interface IconProps extends LucideProps {
name: keyof typeof dynamicIconImports;
export type IconNames = keyof typeof Lucide.icons;
interface IconProps extends Lucide.LucideProps {
name: IconNames;
}

const Icon = ({ name, ...props }: IconProps) => {
const LucideIcon = dynamic(dynamicIconImports[name])
const LucideIcon = dynamic(() => import(`lucide-react`).then((mod) => mod[name]));

return <LucideIcon {...props} />;
};

export default Icon;
export type { IconProps };
```