Using react-beautiful-dnd with Next.js and TypeScript
Introduction
react-beautiful-dnd
is a higher level abstraction specifically built for lists (vertical, horizontal, movement between lists, nested lists and so on). Within that subset of functionalityreact-beautiful-dnd
offers a powerful, natural and beautiful drag and drop experience. However, it does not provide the breadth of functionality offered byreact-dnd
. Soreact-beautiful-dnd
might not be for you depending on what your use case is.
Motivation
Although it’s straight forward to implement it inside your React application according to its API documentation, it still requires additional configuration in order to make it work in your Next.js application. So, this post will walk you through step by step on how to set up react-beautiful-dnd
and fix the potential issues in a Next.js app (using TypeScript). By the end, a simple todo app is introduced as an example to demonstrate react-beautiful-dnd
+ Next.js + TypeScript in this step-by-step guidance.
Tech Stack
- Next.js — A widely-used framework for building React applications
- TypeScript
- TailwindCSS — A utility-first CSS framework to help you focus on work
- Nvim — Vim-based text editor
Set up Next.js application with TypeScript, TailwindCSS and vim-based text editor
If it’s your first time of trying to set up a Next.js application with TypeScript and Tailwind together with vim-based text editor, then you probably want to check out my previous post — How to set up a next.js application workflow using Neovim, typescript and tailwindCSS.
After this basic setup, let’s move on implement react-beautiful-dnd
in our Next.js application.
Make react-beautiful-dnd
works in Next.js
Let’s try to create a simple drop-and-drag Kanban board using DragDropContext
, Droppable
, and Draggable
, from which you will have a basic understanding about drag and drop.
The drag-and-drop components structure looks like this:
![](https://miro.medium.com/max/1400/1*ox7fdACvi0nxGQYt2WW9WQ.png)
Demo a drag-and-drop app (code repo) built with react-beautiful-dnd
![](https://miro.medium.com/max/1200/1*cE0lfM23H-0bKbFsnw9pCA.gif)
Here are what we want to achieve in the above application:
- building a droppable container
- make list items draggable horizontally (within column) and vertically (between columns)
Step 1: Install dependencies
react-beautiful-dnd
@types/react-beautiful-dnd
(you only need this if working with TypeScript)
Now you could import the API components from react-beautiful-dnd
:
![](https://miro.medium.com/max/1400/1*rJu4Eu7yEX5iFrxT7AnJew.png)
Step 2: Wrap the droppable container with DragDropContext
API
![](https://miro.medium.com/max/1400/1*YzgZ1AWwyu436EYSl8iLZA.png)
Tip: Don’t worry if you could view the whole picture of the React component as the code repo link is shared by the end of this post.
Step 3: Building droppable containers using Droppable API
Building droppable containers to allow items to be draggable horizontally and vertically.
![](https://miro.medium.com/max/1400/1*sjcwWwng5lIFdRuyMHwJmg.png)
Don’t get overwhelmed by the above code. The only thing you need to understand is that a Droppable container is created using Droppable
component, and you must provide droppableId
which could be any unique string, and a callback function: (droppableProvided) => (..ref={droppableProvided.innerRef} {…droppableProvided.droppableProps})
. That’s all for creating a Droppable container. In the next, we will create Draggable component to be
Step 3: Implement Draggable feature inside Droppable containers using Draggable API
![](https://miro.medium.com/max/1400/1*u33a5GMkwMxQdwCHFu9Vrw.png)
Same as Droppable component, we also need to provide a draggableId
which is any unique string, and a callback function: (draggableProvided) => (..ref={draggableProvided.innerRef} {…draggableProvided.draggableProps} {...draggableProvided.draghandleProps).
Step 4: Run your Next.js application and issues occur
Issue #1: Unable to find any drag handles in the context “0”
![](https://miro.medium.com/max/1400/1*uQwC3N7E2EXI31yPjCrlEw.png)
Solution: Override Document
The server side rendering feature of Next.js could mess up how a library operates, and one such library is react-beautiful-dnd.
To fix the above issue, we need to use resetServerContext
call inside Document
so that the markup from the server doesn’t conflict with what the client side library(dependency) expects (react-beautiful-dnd
in our case). Then we need to override the default Document
(pages/_document.js
), which is shown below:
![](https://miro.medium.com/max/1400/1*m954Hvbya58YLLvZnlS09g.png)
_document
here: https://nextjs.org/docs/advanced-features/custom-documentWe need to import resetServerContext
from react-beautiful-dnd
and call it in our getInitialProps
before we return. So, here is what_document
looks like:
![](https://miro.medium.com/max/1400/1*t-etUvdRMWUOGPe3H-X46A.png)
Issue #2: Cannot find droppable entry with id
Up to now, you might still see problems similar to below:
![](https://miro.medium.com/max/1400/1*XFgoTVmssiCNda1esYB1-A.png)
Solution: remove reactStrictMode
You could find this issue discussed as well in Github issue page. Not too bad as it only happens in development env, but not in production env. Yet, to make our development easy, we simply need to comment out the below code inside next.config.js
// reactStrictMode: true,
Build a todo app using react-beautiful-dnd + Next.js + TypeScript
You could find a Todo app using react-beautiful-dnd
in the repo: https://github.com/amy-juan-li/example-dnd-todo