1

Basics:

  • NextJS 14.2.16

  • Pages Router

  • VSCode IDE (latest version)

  • Flask is the backend, NextJS is only used to serve a React front-end.

Goal:

  • Debug web app with Chrome using a user profile that has chrome extensions loaded in it.

  • Have all breakpoints actually be reachable.

My launch.json configuration works only if I do not specify any Chrome profile and then I am unable to use browser debugging tools like React Dev tools or Redux Dev tools, so I really need my own profile to load. When using this configuration (I launch using Full Stack compound):

{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Launch Chrome",
            "type": "chrome",
            "request": "launch",
            "url": "http://localhost:3000",
            "webRoot": "${workspaceFolder}/nextjs",
            "sourceMaps": true,
            "sourceMapPathOverrides": {
                "webpack://?:*/*": "${workspaceFolder}/nextjs/*",
            },
            "userDataDir": false,
            "runtimeArgs": [
                 "--profile-directory=Profile 3",
            ],
        },
        {
            "name": "Launch NextJS",
            "type": "node-terminal",
            "request": "launch",
            "cwd": "${workspaceFolder}/nextjs",
            "command": "npm run dev",
            "serverReadyAction": {
                "action": "startDebugging",
                "pattern": "- Local:\\s*(https?://.+)",
                "name": "Launch Chrome",
            }
        },
        {
            "name": "Launch Flask",
            "type": "debugpy",
            "request": "launch",
            "module": "flask",
            "cwd": "${workspaceFolder}/flask/api",
            "env": {
                "FLASK_APP": "run.py",
                "FLASK_DEBUG": "1"
            },
            "args": ["run", "--no-debugger", "--no-reload"],
            "justMyCode": true
        },
    ],
    "compounds": [
        {
            "name": "Full Stack",
            "configurations": ["Launch Flask", "Launch NextJS"]
        }
    ]
}

The Chrome window will open with the correct user profile and extensions loaded, but it remains on an "about:blank" page and will not load my application until I manually type in "localhost:3000" to the URL bar, then it loads the application but my breakpoints don't work. The weird thing is, in VSCode, the breakpoints act like they will be hit, they light up red and aren't gray empty circles, but they never do get hit when they should and when I Diagnose Breakpoints with the command palette, they come up as unbound saying source locations couldn't be found.

The terminal output of NextJS is this, it never attempts to move to the compiling step by itself:

(chap) 1234567:nextjs xxx$ npm run dev
Debugger attached.

> [email protected] dev
> next dev

Debugger attached.
Debugger attached.
  ▲ Next.js 14.2.16
  - Local:        http://localhost:3000
  - Environments: .env.development

 ✓ Starting...
 ✓ Ready in 1892ms

I have tried many different regex patterns for NextJS to match on, but I don't think that's the problem because Chrome does launch, it just doesn't load the application by itself.

I have tried this configuration also, launching with the Debug Full Stack compound:

{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Launch Flask",
            "type": "debugpy",
            "request": "launch",
            "module": "flask",
            "cwd": "${workspaceFolder}/flask/api",
            "env": {
                "FLASK_APP": "run.py",
                "FLASK_DEBUG": "1"
            },
            "args": ["run", "--no-debugger", "--no-reload"],
            "justMyCode": true
        },
        {
            "name": "Launch NextJS",
            "type": "node",
            "request": "launch",
            "runtimeExecutable": "node",
            "runtimeArgs": ["--inspect", "./node_modules/next/dist/bin/next"],
            "cwd": "${workspaceFolder}/nextjs",
            "skipFiles": ["<node_internals>/**"], 
        },
        {
            "name": "Launch Chrome",
            "type": "chrome",
            "request": "launch",
            "url": "http://localhost:3000",
            "webRoot": "${workspaceFolder}/nextjs",
            "runtimeArgs": [
                "--load-extension=/Users/xxx/Library/Application Support/Google/Chrome/Default/Extensions/fmkadmapgofadopljbjfkapdkoienihi/6.1.5_0"
            ],
        }
    ],
    "compounds": [
    {
      "name": "Debug Full Stack",
      "configurations": ["Launch Flask", "Launch NextJS", "Launch Chrome"]
    }
  ]
}

This opens Chrome, automatically loads the application and breakpoints work, but no profile is loaded and the extension doesn't load either. I think Chrome must have a profile in order for --load-extension to work.

I'm really out of ideas at this point as I have tried so many different configurations founds via stackoverflow and nextjs's git issues, but none really deal with chrome profiles (most people use debugWithChrome under serverReadyAction in their full stack config which will not work for this).

Has anybody gotten another Chrome profile to work successfully with NextJS and VSCode debugging?

Edit: Looks like --load-extension is a deprecated flag/feature of Chrome and no longer is usable, so that's one problem clarified.

1 Answer 1

0

I spent all day on this, finally decided to write a post, and then found my answer within another hour or so, go figure. Anyway, the key is the make a chrome profile outside of the normal location Chrome stores profiles, then point VSCode to that with the userDataDir setting and not passing any runtimeArgs. Another helpful tool I found was being able to view the profile path Chrome is using by going to chrome://version on the Chrome window your launch config opens. I have not tested these solutions with turbopack yet so a word of warning there.

Here are the steps. They're relevant to my setup (flask & nextjs), but I imagine could be adapted to other setups fairly easily:

  1. In your launch configuration for Chrome, set userDataDir to a directory that is NOT where Chrome normally stores profiles (on Mac, Chrome normally stores profiles here, in Sept 2025, /Users/username/Library/Application Support/Google/Chrome). You can set userDataDir to a directory that doesn't yet exist and it'll create it for you, so, I decided to just have it create a folder in my Documents area: "userDataDir": "/Users/xxx/Documents/debug-profile". My launch config now looks like this; you'll need to edit the userDataDir, url, webRoot, cwd, FLASK_APP, as relevant to your wishes and application.

    {
        "version": "0.2.0",
        "configurations": [
            {
                "name": "Launch Chrome",
                "type": "chrome",
                "request": "launch",
                "url": "http://localhost:3000",
                "webRoot": "${workspaceFolder}/nextjs",
                "userDataDir": "/Users/xxx/Documents/debug-profile",
            },
            {
                "name": "Launch NextJS",
                "type": "node-terminal",
                "request": "launch",
                "cwd": "${workspaceFolder}/nextjs",
                "command": "npm run dev",
                "serverReadyAction": {
                    "action": "startDebugging",
                    "pattern": "- Local:\\s*(https?://.+)",
                    "name": "Launch Chrome",
                }
            },
            {
                "name": "Launch Flask",
                "type": "debugpy",
                "request": "launch",
                "module": "flask",
                "cwd": "${workspaceFolder}/flask/api",
                "env": {
                    "FLASK_APP": "run.py",
                    "FLASK_DEBUG": "1"
                },
                "args": ["run", "--no-debugger", "--no-reload"],
                "justMyCode": true
            },
        ],
        "compounds": [
            {
                "name": "Full Stack",
                "configurations": ["Launch Flask", "Launch NextJS"]
            }
        ]
    }
    
  2. Launch Full Stack from the debugger panel in VS Code. This spins up the flask backend and NextJS front end, and also spawns a Chrome window that should automatically load your application. There will not be a profile loaded. Make sure your breakpoints are hit before continuing. If they're not, figure out that issue first.

  3. Click the 3-dot icon next to the person icon in the upper right of the chrome window > Extensions > Visit Chrome Web Store and install any extensions you need on this profile. Do not sign in; this strategy will not work with signing in before doing some other work first. If you need to use a signed-in profile, see how to do that below.

  4. Stop and restart your debugging config. It should now load with the somewhat anonymous user profile and extensions you just installed.

When you install all the extensions, VSCode (or Chrome?) creates the /Default and /Extensions folders at the path you specified as the userDataDir. From what I can reason, I think this will persist indefinitely, as long as the directory VSCode is pointed to in the userDataDir variable still exists. It's important to note that the userDataDir is set one directory level above /Default, which is the name of the first profile in Chrome and is where /Extensions actually lives.

That's all you should need to do to get your debugging working, assuming your source maps and everything are in order and you don't need a signed-in profile.

"BUT I NEED A SIGNED-IN PROFILE"
As an extra side quest adventure, I attempted the above with a signed-in profile, but found out quickly that Chrome thinks it's unsecure and won't let you sign in because VSCode is controlling the browser. To get around this, you first need to create the signed-in profile through an attach process and then after you do that once, you can rewrite your launch config to use the signed-in profile through a launch process. Here are the steps:

  1. Make a launch.json config that looks like this. Edit cwd, FLASK_APP, urlFilter, and webRoot as fits your application.

    {
        "version": "0.2.0",
        "configurations": [
            {
                "name": "Launch NextJS",
                "type": "node-terminal",
                "request": "launch",
                "cwd": "${workspaceFolder}/nextjs",
                "command": "npm run dev",
            },
            {
                "name": "Launch Flask",
                "type": "debugpy",
                "request": "launch",
                "module": "flask",
                "cwd": "${workspaceFolder}/flask/api",
                "env": {
                    "FLASK_APP": "run.py",
                    "FLASK_DEBUG": "1"
                },
                "args": ["run", "--no-debugger", "--no-reload"],
                "justMyCode": true
            },
            {
                "name": "Attach to Chrome",
                "type": "chrome",
                "request": "attach",
                "port": 9222,
                "urlFilter": "http://localhost:3000/*",
                "webRoot": "${workspaceFolder}/nextjs",
            }
        ],
        "compounds": [
            {
                "name": "Full Stack",
                "configurations": ["Launch Flask", "Launch NextJS"]
            }
        ]
    }
    
  2. Run the Full Stack command from the debug panel. With the backend and frontend running, open terminal (if you're on Windows your commands will be slightly different; you'll need to google those) and launch Chrome with the remote-debugging-port enabled and a directory defined that doesn't yet exist for the --user-data-dir arg. Do not map the --user-data-dir to the normal place where Chrome stores these profiles; you should set it to a directory that's logical to store a fresh profile for your project. Even if the directory doesn't exist yet, it will be made for you upon running the command. This is what mine looked like:

    /Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --remote-debugging-port=9222 —-user-data-dir=/Users/username/Documents/signed-in-debug-profile
    
  3. Chrome will launch a window prompting you to sign in. Sign in now. You could try syncing your profile and maybe that would avoid having to do step 4, I'm not sure, I opted not to sync them as I didn't want to mess anything up in my google account by testing stuff.

  4. Now that you're logged in, go to Extensions > Visit Chrome Web Store > install any extensions you need.

  5. Navigate to the URL your web app is running on. In my example, this is localhost:3000.

  6. Now attach to this process; back in VSCode, in the debug panel, run the "Attach to Chrome" debug configuration. The Call Stack should show it running as well as your backend and frontend. Set some breakpoints and go back to the browser with your app running and do whatever you need to do to test that your breakpoints get hit. Your installed extensions should be available as well. Assuming all works, proceed to step 7.

  7. Now that you've created a signed-in-profile independent of VSCode running Chrome's window, you can exit out and stop your debugger. Make sure you quit Chrome altogether because only one instance of Chrome can be running using your user profile when running a Chrome debugging session in VSCode and utilizing the useDataDir property in launch.json.

  8. Back in your launch.json, rewrite your config to utilize the new profile you created at /Users/username/Documents/signed-in-debug-profile (or wherever you put it) in a launch process for Chrome instead of having to use attach again. Mine looks like this:

    {
        "version": "0.2.0",
        "configurations": [
            {
                "name": "Launch Chrome",
                "type": "chrome",
                "request": "launch",
                "url": "http://localhost:3000",
                "webRoot": "${workspaceFolder}/nextjs",
                "userDataDir": "/Users/username/Documents/signed-in-debug-profile",
            },
            {
                "name": "Launch NextJS",
                "type": "node-terminal",
                "request": "launch",
                "cwd": "${workspaceFolder}/nextjs",
                "command": "npm run dev",
                "serverReadyAction": {
                    "action": "startDebugging",
                    "pattern": "- Local:\\s*(https?://.+)",
                    "name": "Launch Chrome",
                }
            },
            {
                "name": "Launch Flask",
                "type": "debugpy",
                "request": "launch",
                "module": "flask",
                "cwd": "${workspaceFolder}/flask/api",
                "env": {
                    "FLASK_APP": "run.py",
                    "FLASK_DEBUG": "1"
                },
                "args": ["run", "--no-debugger", "--no-reload"],
                "justMyCode": true
            },
        ],
        "compounds": [
            {
                "name": "Full Stack",
                "configurations": ["Launch Flask", "Launch NextJS"]
            }
        ]
    }
    
  9. Run the Full Stack command in the debugger panel and test if VSCode launches a Chrome window with your signed-in profile, extensions, and working breakpoints. Good luck.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.