nuxt: Upgrading to nuxt 3.5.0 breaks router.js

Environment

  • Operating System: Darwin
  • Node Version: v16.19.0
  • Nuxt Version: 3.4.3
  • Nitro Version: 2.4.0
  • Package Manager: pnpm@8.5.1
  • Builder: vite
  • User Config: app, modules, ssr, css, unocss, build, runtimeConfig, sourcemap
  • Runtime Modules: design@1.0.0, @pinia/nuxt@0.4.10, @unocss/nuxt@0.51.13
  • Build Modules: -

Reproduction

Upgrading the nuxt 3.4.3 to 3.5.0, changing in the package.json manually or doing the nuxi upgrade --force code.

Describe the bug

After making the upgrade and running pnpm run dev, the page breaks, showing these error:

Uncaught SyntaxError: ambiguous indirect export: hasInjectionContext

Opening the file, shows these line of code that has the error:

import { getCurrentInstance, hasInjectionContext, inject, onUnmounted } from “/_nuxt/node_modules/.cache/vite/client/deps/vue.js?v=ea0c84f2”;

Additional context

No response

Logs

import { getCurrentInstance, hasInjectionContext, inject, onUnmounted } from "/_nuxt/node_modules/.cache/vite/client/deps/vue.js?v=ea0c84f2";
import { sanitizeStatusCode } from "/_nuxt/@fs/Users/mateus/Documents/projects/afiliapay/apps/node_modules/.pnpm/h3@1.6.6/node_modules/h3/dist/index.mjs?v=925cd65c";
import { hasProtocol, joinURL, parseURL } from "/_nuxt/@fs/Users/mateus/Documents/projects/afiliapay/apps/node_modules/.pnpm/ufo@1.1.2/node_modules/ufo/dist/index.mjs?v=925cd65c";
import { useNuxtApp, useRuntimeConfig } from "/_nuxt/@fs/Users/mateus/Documents/projects/afiliapay/apps/node_modules/.pnpm/nuxt@3.5.0_@types+node@20.1.5_sass@1.62.1/node_modules/nuxt/dist/app/nuxt.js?v=925cd65c";
import { createError } from "/_nuxt/@fs/Users/mateus/Documents/projects/afiliapay/apps/node_modules/.pnpm/nuxt@3.5.0_@types+node@20.1.5_sass@1.62.1/node_modules/nuxt/dist/app/composables/error.js?v=925cd65c";
import { useState } from "/_nuxt/@fs/Users/mateus/Documents/projects/afiliapay/apps/node_modules/.pnpm/nuxt@3.5.0_@types+node@20.1.5_sass@1.62.1/node_modules/nuxt/dist/app/composables/state.js?v=925cd65c";
export const useRouter = () => {
  return useNuxtApp()?.$router;
};
export const useRoute = () => {
  if (process.dev && isProcessingMiddleware()) {
    console.warn("[nuxt] Calling `useRoute` within middleware may lead to misleading results. Instead, use the (to, from) arguments passed to the middleware to access the new and old routes.");
  }
  if (hasInjectionContext()) {
    return inject("_route", useNuxtApp()._route);
  }
  return useNuxtApp()._route;
};
export const onBeforeRouteLeave = (guard) => {
  const unsubscribe = useRouter().beforeEach((to, from, next) => {
    if (to === from) {
      return;
    }
    return guard(to, from, next);
  });
  onUnmounted(unsubscribe);
};
export const onBeforeRouteUpdate = (guard) => {
  const unsubscribe = useRouter().beforeEach(guard);
  onUnmounted(unsubscribe);
};
export const defineNuxtRouteMiddleware = (middleware) => middleware;
export const addRouteMiddleware = (name, middleware, options = {}) => {
  const nuxtApp = useNuxtApp();
  const global = options.global || typeof name !== "string";
  const mw = typeof name !== "string" ? name : middleware;
  if (!mw) {
    console.warn("[nuxt] No route middleware passed to `addRouteMiddleware`.", name);
    return;
  }
  if (global) {
    nuxtApp._middleware.global.push(mw);
  } else {
    nuxtApp._middleware.named[name] = mw;
  }
};
const isProcessingMiddleware = () => {
  try {
    if (useNuxtApp()._processingMiddleware) {
      return true;
    }
  } catch {
    return true;
  }
  return false;
};
export const navigateTo = (to, options) => {
  if (!to) {
    to = "/";
  }
  const toPath = typeof to === "string" ? to : to.path || "/";
  const isExternal = options?.external || hasProtocol(toPath, { acceptRelative: true });
  if (isExternal && !options?.external) {
    throw new Error("Navigating to external URL is not allowed by default. Use `navigateTo (url, { external: true })`.");
  }
  if (isExternal && parseURL(toPath).protocol === "script:") {
    throw new Error("Cannot navigate to an URL with script protocol.");
  }
  const inMiddleware = isProcessingMiddleware();
  if (process.client && !isExternal && inMiddleware) {
    return to;
  }
  const router = useRouter();
  if (process.server) {
    const nuxtApp = useNuxtApp();
    if (nuxtApp.ssrContext) {
      const fullPath = typeof to === "string" || isExternal ? toPath : router.resolve(to).fullPath || "/";
      const location2 = isExternal ? toPath : joinURL(/* #__PURE__ */ useRuntimeConfig().app.baseURL, fullPath);
      async function redirect() {
        await nuxtApp.callHook("app:redirected");
        const encodedLoc = location2.replace(/"/g, "%22");
        nuxtApp.ssrContext._renderResponse = {
          statusCode: sanitizeStatusCode(options?.redirectCode || 302, 302),
          body: `<!DOCTYPE html><html><head><meta http-equiv="refresh" content="0; url=${encodedLoc}"></head></html>`,
          headers: { location: location2 }
        };
        return inMiddleware ? (
          /* abort route navigation */
          false
        ) : void 0;
      }
      if (!isExternal && inMiddleware) {
        router.afterEach((final) => final.fullPath === fullPath ? redirect() : void 0);
        return to;
      }
      return redirect();
    }
  }
  if (isExternal) {
    if (options?.replace) {
      location.replace(toPath);
    } else {
      location.href = toPath;
    }
    return Promise.resolve();
  }
  return options?.replace ? router.replace(to) : router.push(to);
};
export const abortNavigation = (err) => {
  if (process.dev && !isProcessingMiddleware()) {
    throw new Error("abortNavigation() is only usable inside a route middleware handler.");
  }
  if (err) {
    throw createError(err);
  }
  return false;
};
export const setPageLayout = (layout) => {
  if (process.server) {
    if (process.dev && getCurrentInstance() && useState("_layout").value !== layout) {
      console.warn("[warn] [nuxt] `setPageLayout` should not be called to change the layout on the server within a component as this will cause hydration errors.");
    }
    useState("_layout").value = layout;
  }
  const nuxtApp = useNuxtApp();
  if (process.dev && nuxtApp.isHydrating && nuxtApp.payload.serverRendered && useState("_layout").value !== layout) {
    console.warn("[warn] [nuxt] `setPageLayout` should not be called to change the layout during hydration as this will cause hydration errors.");
  }
  const inMiddleware = isProcessingMiddleware();
  if (inMiddleware || process.server || nuxtApp.isHydrating) {
    const unsubscribe = useRouter().beforeResolve((to) => {
      to.meta.layout = layout;
      unsubscribe();
    });
  }
  if (!inMiddleware) {
    useRoute().meta.layout = layout;
  }
};

About this issue

  • Original URL
  • State: closed
  • Created a year ago
  • Reactions: 1
  • Comments: 16 (7 by maintainers)

Most upvoted comments

I can confirm, adding this to package.json fixes error: “vue”: “3.3.2”,

You just have to remove below code from your package.json:

"overrides": {
    "vue": "latest"
  }

I had a similar issue with the hasInjectionContext import. yarn why vue showed that I had Vue 3.2.47 set in my package.json file. Removing this, and installing dependencies again resolved the issue by upgrading me to Vue 3.3.2.

Make sure your vue version is also upgraded - it should be at least 3.3.1.

Im using nuxt 3 (3.5.1) and my package.json as:

{
  "name": "app",
  "private": true,
  "scripts": {
    "build": "nuxt build",
    "dev": "nuxt dev",
    "generate": "nuxt generate",
    "preview": "nuxt preview",
    "postinstall": "nuxt prepare"
  },
  "devDependencies": {
    "@sidebase/nuxt-auth": "^0.6.0-beta.2",
    "@types/node": "^20.2.3",
    "nuxt": "^3.5.1"
  }
}

why the solution is adding vue ?, nuxt is using behind the scenes vue 3 right ?, im confused a little explanation would be great!.

And I’m facing the same problem right now. After Login im trying to await navigateTo({ path: '/admin/test' }) and nuxt is threating the TO as external…

image

pages/admin/test.vue is there.

image

Close

No, the problem is almost certainly that you have an older version of vue still installed. You can also try removing node_modules/.vite and .nuxt to be sure that vite’s cached files are regenerated.

If that doesn’t work, please do provide a reproduction and I’ll happily take a look.