Setting up a DAP-debugger for NextJS with Nvim is a little complicated; in my opinion, it might be one of the situations where it's better to use a GUI editor like VSCode. Though I must admit, seeing clientside console logs in your editor is really nice when you want to quickly do certain things. I'm not the most experienced vim user, so please let me know if there are any mistakes here. But this gets things up and running, and it should look like the picture below:
I use lazyvim, with nvim 0.11.1, and mason is used to install LSPs and DAPs. You will need to configure these main plugins; the first being Mason. You can disable lazy, I just enabled it for a faster start-up time:
1local LSPS = {2 "tailwindcss",3 "gopls",4 "html",5 "emmet_language_server",6 "cssls",7}89-- dap10-- "js-debug-adapter",11-- "chrome-debug-adapter",1213return {14 "williamboman/mason-lspconfig.nvim",15 event = "VeryLazy",16 opts = {17 ensure_installed = LSPS,18 },19}
My Nvim-Dap configuration is below:
1return {2 "mfussenegger/nvim-dap",3 lazy = true,4 event = "VeryLazy",5 dependencies = {6 { "theHamsta/nvim-dap-virtual-text", config = true },7 { "rcarriga/nvim-dap-ui", dependencies = { "nvim-neotest/nvim-nio" }, config = true },8 },9 config = function()10 require("dap").adapters["pwa-node"] = {11 type = "server",12 host = "localhost",13 port = 8123,14 executable = {15 command = os.getenv("HOME") .. "/.local/share/nvim/mason/bin/js-debug-adapter",16 },17 }1819 require("dap").adapters["chrome"] = {20 type = "executable",21 command = "node",22 args = {23 os.getenv("HOME") .. "/.local/share/nvim/mason/packages/chrome-debug-adapter/out/src/chromeDebug.js",24 },25 }2627 local dap = require("dap")28 local js_based_languages = { "typescript", "javascript", "typescriptreact", "javascriptreact" }29 for _, language in ipairs(js_based_languages) do30 dap.configurations[language] = {31 {32 name = "Next.js: debug server",33 type = "pwa-node",34 request = "launch",35 program = "${workspaceFolder}/node_modules/next/dist/bin/next",36 runtimeArgs = { "--inspect" },37 skipFiles = { "<node_internals>/**" },38 serverReadyAction = {39 action = "debugWithChrome",40 killOnServerStop = true,41 pattern = "- Local:.+(https?://.+)",42 uriFormat = "%s",43 webRoot = "${workspaceFolder}",44 },45 cwd = "${workspaceFolder}",46 },47 {48 name = "Next.js: debug client-side",49 type = "chrome",50 request = "launch",51 url = "http://localhost:3000",52 webRoot = "${workspaceFolder}",53 sourceMaps = true,54 sourceMapPathOverrides = {55 ["webpack://_N_E/*"] = "${webRoot}/*",56 },57 },58 }59 end60 end,61}
Lastly, you will need to set up Nvim-Dap-UI which is also below:
1return {2 "rcarriga/nvim-dap-ui",3 lazy = true,4 event = "VeryLazy",5 dependencies = { "mfussenegger/nvim-dap", "nvim-neotest/nvim-nio" },6}
Once these files are in place, you can install DAPs with :MasonInstall js-debug-adapter
and :MasonInstall chrome-debug-adapter
I have listed my keymaps below as well, but you can use whatever is convenient for you:
1vim.keymap.set("n", "<leader>ddb", function()2 require("dap").toggle_breakpoint()3end, { desc = "Dap - Toggle Breakpoint", noremap = true, silent = true })45vim.keymap.set("n", "<leader>dde", function()6 require("dap").continue()7end, { desc = "Dap - Start/Continue Debugging", noremap = true, silent = true })89vim.keymap.set("n", "<leader>ddt", function()10 require("dap").terminate()11end, { desc = "Dap - Stop Debugging", noremap = true, silent = true })1213vim.keymap.set("n", "<leader>dds", function()14 require("dap").step_over()15end, { desc = "Dap - Step Over", noremap = true, silent = true })1617vim.keymap.set("n", "<leader>ddi", function()18 require("dap").step_into()19end, { desc = "Dap - Step Into", noremap = true, silent = true })2021vim.keymap.set("n", "<leader>ddo", function()22 require("dap").step_out()23end, { desc = "Dap - Step Out", noremap = true, silent = true })2425vim.keymap.set("n", "<leader>ddr", function()26 require("dap").repl.open()27end, { desc = "Dap - Open Debug REPL", noremap = true, silent = true })2829vim.keymap.set("n", "<leader>ddl", function()30 require("dap").run_last()31end, { desc = "Dap - Run Last Debug Session", noremap = true, silent = true })3233vim.keymap.set("n", "<leader>duo", function()34 require("dapui").open()35end, { desc = "Dap UI - Open", noremap = true, silent = true })3637vim.keymap.set("n", "<leader>duc", function()38 require("dapui").close()39end, { desc = "Dap UI - Close", noremap = true, silent = true })4041vim.keymap.set("n", "<leader>due", function()42 require("dapui").toggle()43end, { desc = "Dap UI - Toggle", noremap = true, silent = true })4445vim.keymap.set("v", "<leader>due", function()46 require("dapui").eval()47end, { desc = "Dap UI - Evaluate Expression", noremap = true, silent = true })