Open Eduard-Hasa opened 2 years ago
The library should work with NextJS.
The issues you are mentioning seem to be related to trying to copy examples to NextJS and not the core library.
@clauderic Oh sorry you are right. Could I offer a generous donation for a public nextjs example of sortable tree? Technically I got it working but just feel liked I hacked my way too it and seems finicky.
AMAZING library btw. Great Job!
I'm actually planning to release the sortable tree examples as a separate @dnd-kit package (something like @dnd-kit/sortable-tree
), which should make it much easier to consume anywhere, not just for NextJS. Just haven't had time to prioritize this yet.
@clauderic Oh thats a great idea. Would be awesome if you made sure it works with SSR on NextJS as that is going to be one of the more popular use cases I would imagine.
This library is so amazing. Kudos to you. None others come close to it.
@clauderic Is there any way I can become a donor to prioritize this? Could you email me at Ed@Hasahub.com please? Really interested in coming to an agreement together.
@clauderic after a few hours of focus, I actually was able to quite easily get sortable tree working on nextjs. Let me know if you want a PR. Made some minor tweaks to the styling of the Sortable Tree Items as the height was not defined for some reason and caused a bunch of bugs. Simply setting height to content fit fixed it all. My fork was from your react-18-tweaks branch.
@Eduard-Hasa , would you mind sharing your fork since i'm facing the same issues using this lib with nextjs? thanks
@dan852 hey certainly let me find a branch that doesn't contain any sensitive project information.
Until then:
You have to wrap the sortable tree component in a NoSSR component that disables serverside rendering since the sortable tree component needs to access to document object.
Also all of the styling needs to be fixed. I simply went to google and used an online sass compiler and converted all of the css to normal css to remove all the errors.
There was another issue with detecting if the device is iOS and I just made that static to true.
Those were the only major issues I found. Rest was easy
credit: blog post on disabling SSR
import dynamic from 'next/dynamic';
import React from 'react';
const NonSSRWrapper = (props: { children: any }) => <React.Fragment>{props.children}</React.Fragment>;
export default dynamic(() => Promise.resolve(NonSSRWrapper), {
ssr: false,
});
And then you wrap the dnd-kit component with it.
const isSSR = () => typeof window === 'undefined';
export default function Container() {
return (
<div>
<NonSSRWrapper>
{!isSSR() && <MultipleContainers />}
</NonSSRWrapper>
</div>
);
}
Note if you are copying from their storybook examples, the CSS will not work with nextjs and you can use a SCSS -> CSS converter..
You will also need to install the package npm i classnames
to get the storybook examples to work in a nextjs project.
@NishKebab what's dynamic
?
edited: sorry, somehow my eyes didn't see the very obvious link to the blog post. I found my answer.
import dynamic from 'next/dynamic';
edited: updated the original post.
My goal for today was to get the sortable tree working. I utterly failed even when presented with a sandbox example.
Luckily, I found: https://github.com/Shaddix/dnd-kit-sortable-tree
Using that as an example. I was able to get my exact use-case so I thoroughly recommend it.
Also, I'm using NextJS. I did get the SSR issue as well. But I simply use the isMounted Ref trick to ensure that the sortable only runs on client-side.
@paulm17 could you please provide more details about the isMounted
trick?
Also, did you integrated this on Next.js 13 or 12?
@TotomInc You set a ref variable like
const isMountedRef = useRef(false)
and then you have a useEffect only at mount
useEffect(() => {
isMountedRef.current = true
}, [])
and then what you want to run at mount only
<>
{
isMountedRef.current && <>I will only run at mount</>
}
</>
for next.js 13 app directory I hacked something like this:
// app/browser/layout.tsx
import { Providers } from '@/app/providers';
export default async function BrowserLayout({
children,
}: {
children: React.ReactNode;
}) {
return <Providers>{children}</Providers>;
}
// app/providers.tsx
'use client';
import { useDragState } from '@/lib/dragState';
import { DndContext, DragOverlay } from '@dnd-kit/core';
import { ReactNode } from 'react';
export function Providers({ children }: { children: ReactNode }) {
const { activeId, handleDragStart, handleDragEnd } = useDragState();
return (
<DndContext onDragStart={handleDragStart} onDragEnd={handleDragEnd}>
{children}
<DragOverlay>{activeId ? <h1>{activeId}</h1> : null}</DragOverlay>
</DndContext>
);
}
// lib/dragState.ts
'use client';
import type { DragStartEvent } from '@dnd-kit/core';
import { useState } from 'react';
export function useDragState() {
const [activeId, setActiveId] = useState<string | null>(null);
function handleDragStart(event: DragStartEvent) {
setActiveId(event.active.id.toString());
}
function handleDragEnd() {
setActiveId(null);
}
return {
activeId,
handleDragStart,
handleDragEnd,
};
}
also next.js authors recommends starting use client
in libs
// postcss.config.js
module.exports = {
plugins: {
"postcss-import": {}, // add this
"tailwindcss/nesting": {}, // also add this
tailwindcss: {},
autoprefixer: {},
},
};
Further details if you wanna dive into: https://tailwindcss.com/docs/using-with-preprocessors#nesting
npm install postcss postcss-preset-env
// postcss.config.js
module.exports = {
plugins: {
'postcss-preset-env': {
autoprefixer: {},
features: {
'nesting-rules': true,
},
},
},
};
npm install postcss postcss-advanced-variables
// postcss.config.js
module.exports = {
plugins: {
"postcss-advanced-variables": {}, // add this
"postcss-import": {},
"tailwindcss/nesting": {},
tailwindcss: {},
autoprefixer: {},
},
};
No more "selector is not pure" errors from CSS modules 🙂
*** To make CSS nesting rules to work with Next.js:
Option 1 (If you are using Tailwind):
// postcss.config.js module.exports = { plugins: { "postcss-import": {}, // add this "tailwindcss/nesting": {}, // also add this tailwindcss: {}, autoprefixer: {}, }, };
Further details if you wanna dive into: https://tailwindcss.com/docs/using-with-preprocessors#nesting
Option 2:
npm install postcss postcss-preset-env
// postcss.config.js module.exports = { plugins: { 'postcss-preset-env': { autoprefixer: {}, features: { 'nesting-rules': true, }, }, }, };
*** To make variables work which are declared inside of CSS modules:
npm install postcss postcss-advanced-variables
// postcss.config.js module.exports = { plugins: { "postcss-advanced-variables": {}, // add this "postcss-import": {}, "tailwindcss/nesting": {}, tailwindcss: {}, autoprefixer: {}, }, };
No more "selector is not pure" errors from CSS modules 🙂
Is this for Next.js 13. I just upgraded my project from 12 to 13 and now my DnD context is literally destroying the entire page when active. Certain draggable elements disapear and reappear at random and it causes a ton of random artifacting of the positioning of objects on the rest of my page outside the context. Any tips? I'm using tailwind btw. Also i made sure to dynamically import the entire DND context, so no SSR.
@kishansripada yes, I was working with Next 13. I changed some stuff over time but you can see from old commits that I started with the exact same copy https://github.com/tommy-typos/evernote-clone/tree/main/src/components/DndKitSortable/Tree
@kishansripada yes, I was working with Next 13. I changed some stuff over time but you can see from old commits that I started with the exact same copy https://github.com/tommy-typos/evernote-clone/tree/main/src/components/DndKitSortable/Tree
I installed and added tailwindcss/nesting and postcss-import, with no difference. do you think this has something to do with the app directory? I'm sorry for bugging, but there aren't many resources about this specific topic and I'm struggling to troubeshoot.
@kishansripada oh I did with pages directory.
@kishansripada Did you figure it out? I'm thinking about using the app directory as well for a sample project to test out some DnD libraries.
Also, did you add "use client"
at the top? I don't think this library works with RSC in Next 13 without adding the "use client" directive.
@kishansripada Did you figure it out? I'm thinking about using the app directory as well for a sample project to test out some DnD libraries.
Also, did you add
"use client"
at the top? I don't think this library works with RSC in Next 13 without adding the "use client" directive.
Everything words fine without any work arounds, I just had other mistakes I made. It even works server side from what I can tell, although they may be a warning in the console.
Hey everyone,
thank you for your valuable input! I was struggling with Nextjs 14 and DNDKit. However I did discover that you can easily achieve a reasonable good solution with this: https://nextjs.org/docs/app/building-your-application/optimizing/lazy-loading just switch between APP or Page directory (left top corner of Sidebar). I am using the App-Directory solution with Suspense and React.lazy. Works perfectly fine. Thank you for this awesome lib!
Considering how popular NextJS is I was wondering if you guys will consider supporting it? I got it working after jumping through a few hoops but unfortunately still facing errors.
First issue was nextjs not allowing global selectors in css modules. I solved that by using a saas compiler to give me pure css. Now facing issues like
Would be so amazing if we could get sortableTree example in nextjs. Would honestly not mind donating a good amount to see this support come to light.