Nuxt instance unavailable when trying to run useRuntimeConfig in a file within utils directory during server side rendering (SSR)
Asked Answered
A

3

6

I'm building a website in Nuxt 3 for frontend with SSR, and Laravel in the backend. In the Nuxt 3 project, I have an ApiBridge.js file in the utils directory that I use to organize API calls, set the base URL etc. Since starting the project, I've been running this with server side rendering turned off for my convenience, but when I try to run this with SSR on (Turned on in nuxt.config.js), I get a "Nuxt instance unavailable" error. I'm working on this project while learning Nuxt 3 on the go, so I might be missing something obvious.

import axios from "axios";

const runtimeConfig = useRuntimeConfig()

const api = axios.create({
    baseURL: runtimeConfig?.API_BASE_URL,
    withCredentials: true,
});


const apiBridge = {
    login: (info) => api.post('/login', {
        ...info,
    }),

    register: (info) => api.post('/register', {
        ...info,
    })

    /* .... */
}

export default apiBridge;

Why is this happening? Is this a bad way to do this? How to fix it? Why's it working with SSR turned off? Is it because of the auto imports? Thanks in advance!

Looked around the web but found nothing useful.

EDIT: nuxt.config.js as requested by a comment

// https://nuxt.com/docs/api/configuration/nuxt-config
export default defineNuxtConfig({
    modules: [
        '@nuxtjs/tailwindcss',
        [
            '@pinia/nuxt',
            {
                autoImports: [
                    // automatically imports `defineStore`
                    'defineStore', // import { defineStore } from 'pinia'
                    // automatically imports `defineStore` as `definePiniaStore`
                    ['defineStore', 'definePiniaStore'], // import { defineStore as definePiniaStore } from 'pinia'
                ],
            },
        ],
    ],
    tailwindcss: {
        configPath: './tailwind.config.js'
    },
    build: {

    },
    // ssr: false, // remove later
    runtimeConfig: {
        public: {
            BASE_URL: process.env.BASE_URL,
            API_BASE_URL: process.env.API_BASE_URL,
        }
    },
})
Armored answered 26/2, 2023 at 22:2 Comment(1)
Please add your nuxt.config fileEricaericaceous
A
6

After some back and forth, I ended up moving the apiBridge to the composables directory and changing it to be a Nuxt 3 composable. I assume this is the way it should be done in Nuxt 3. It does look neat, and gets the job done.

import axios from "axios"

export const useApiBridge = () => {
    const runtimeConfig = useRuntimeConfig()

    const api = axios.create({
        baseURL: runtimeConfig.API_BASE_URL,
        withCredentials: true,
    });

    return {   
        login: (info) => api.post('/login', {
            ...info,
        }),

        register: (info) => api.post('/register', {
            ...info,
        })
    }
}

and then in components and other files I use it like

const apiBridge = useApiBridge()
Armored answered 27/2, 2023 at 1:9 Comment(1)
This is part of the solution for me. Now I need to find a way to run your useApiBridge in a middleware or a plugin. When I try to do it I get "Nuxt instance unavailable" error again 😩Talavera
T
4

You can also resolve this by accessing the runtime configuration with:

useNuxtApp().$config

I had the exact same error as you except I was trying to access useRuntimeConfig() in a plugin and this resolved it.

Theorem answered 14/12, 2023 at 17:3 Comment(0)
C
3

The error message "Nuxt instance unavailable" typically occurs when trying to access Nuxt's instance before it has been created or after it has been destroyed. This error can occur when trying to access Nuxt's context or plugins from outside of Nuxt's lifecycle hooks.

In your case, it seems that the useRuntimeConfig() function, which I assume is provided by a Nuxt plugin or module, is being called outside of Nuxt's lifecycle hooks. This function is likely not available when running with SSR because the server-side rendering process is separate from the client-side rendering process, and does not have access to the Nuxt instance.

One way to fix this is to move the useRuntimeConfig() call inside a Nuxt lifecycle hook, such as asyncData() or fetch(). This will ensure that the Nuxt instance is available when the function is called. You can then pass the API_BASE_URL to the ApiBridge module as a parameter or through the nuxtServerInit() action.

Another way to fix this is to use environment variables instead of runtime config. You can set environment variables in the .env file or in your hosting environment, and access them using process.env. This way, the API base URL can be set during the build process and will be available both server-side and client-side.

Regarding your question about why this is working with SSR turned off, it could be because the useRuntimeConfig() function is being called during the client-side rendering process, where the Nuxt instance is available. However, this is not a reliable solution and can lead to issues when running with SSR.

In general, it's a good practice to avoid accessing the Nuxt instance outside of its lifecycle hooks and to use proper dependency injection techniques to pass variables and dependencies to your modules and components.

Coldiron answered 26/2, 2023 at 22:13 Comment(2)
useRuntimeConfig() is what they call a composable in Nuxt 3. Your answer did not help unfortunately. You can't use process.env like that in Nuxt 3 from what I'm aware. Nuxt 3 doesn't have nuxtServerInit either (I've checked the docs, didn't find it).Armored
I'm using it in a clientside plugin and apparently the whole point of runtimeconfig is to avoid env variables leaking?Eclogite

© 2022 - 2024 — McMap. All rights reserved.