Advanced

Token Storage

How to work with storage with enabled token-based authentication

Usage

Token storage is used for keeping authentication token value from the Laravel API available for module consumption during requests assembling.

Storage is used only when sanctum.mode equals to token in your nuxt configuration:

nuxt.config.ts
export default defineNuxtConfig({
  modules: ["nuxt-auth-sanctum"],

  sanctum: {
    // ...
    mode: "token",
    // ...
  },
});
By default, if there is no custom token storage defined, cookies will be used.

How it works

Each token storage implements the following interface:

/**
 * Handlers to work with authentication token.
 */
export interface TokenStorage {
  /**
   * Function to load a token from the storage.
   */
  get: (app: NuxtApp) => Promise<string | undefined>;
  /**
   * Function to save a token to the storage.
   */
  set: (app: NuxtApp, token?: string) => Promise<void>;
}

After the user sends credentials to the API module passes a token from the response to set method as well as the current Nuxt application instance to allow calls like app.runWithConext().

Once the user logs out, the module sends undefined as a token value to reset the stored value.

Before each request against the API, the module loads the token by calling get method with Nuxt instance passed.

Define token storage

You can define your own handler in the app.config.ts configuration file and it will be automatically used by the module:

The app.config.ts approach only works in dev mode and Node.js production builds. When using nuxt generate (static builds for platforms like Capacitor/Ionic), functions are stripped during JSON serialization and the custom tokenStorage won't work.
For static builds, use the plugin approach described below instead.
app/app.config.ts
// LocalStorage example for Laravel Authentication token
const tokenStorageKey = "sanctum.storage.token";
const localTokenStorage: TokenStorage = {
  get: async () => {
    if (import.meta.server) {
      return undefined;
    }

    return window.localStorage.getItem(tokenStorageKey) ?? undefined;
  },

  set: async (app: NuxtApp, token?: string) => {
    if (import.meta.server) {
      return;
    }

    if (!token) {
      window.localStorage.removeItem(tokenStorageKey);
      return;
    }

    window.localStorage.setItem(tokenStorageKey, token);
  },
};

export default defineAppConfig({
  sanctum: {
    tokenStorage: localTokenStorage,
  },
});

Now your application will store tokens in a local storage of your browser.

Keep in mind, localStorage is not available for SSR mode, so you should turn it off in your nuxt.config.ts.

Using a Plugin

For applications built with nuxt generate (e.g., Capacitor/Ionic mobile apps), define the token storage in a client-side plugin instead of app.config.ts:

plugins/sanctum-storage.client.ts
export default defineNuxtPlugin(() => {
  updateAppConfig({
    sanctum: {
      tokenStorage: {
        async get() {
          const { Preferences } = await import("@capacitor/preferences");
          const result = await Preferences.get({ key: "sanctum.token" });

          return result.value ?? undefined;
        },
        async set(_app, token?: string) {
          const { Preferences } = await import("@capacitor/preferences");

          if (token) {
            await Preferences.set({ key: "sanctum.token", value: token });
          } else {
            await Preferences.remove({ key: "sanctum.token" });
          }
        },
      },
    },
  });
});

This approach works with static builds because plugins are compiled by Vite into the JavaScript bundle, preserving the functions.

To ensure the token storage is set before the sanctum module initializes, you need to disable the automatic initial identity request and manually initialize it after your token storage is configured:
nuxt.config.ts
export default defineNuxtConfig({
  modules: ["nuxt-auth-sanctum"],

  sanctum: {
    // ...
    client: {
      initialRequest: false,
    },
  },
});
Then in your plugin, call init() after updating the app config:
plugins/sanctum-storage.client.ts
export default defineNuxtPlugin(async (nuxtApp) => {
  updateAppConfig({
    sanctum: {
      tokenStorage: {
        async get() {
          const { Preferences } = await import("@capacitor/preferences");
          const result = await Preferences.get({ key: "sanctum.token" });

          return result.value ?? undefined;
        },
        async set(_app, token?: string) {
          const { Preferences } = await import("@capacitor/preferences");

          if (token) {
            await Preferences.set({ key: "sanctum.token", value: token });
          } else {
            await Preferences.remove({ key: "sanctum.token" });
          }
        },
      },
    },
  });

  const { init } = useSanctumAuth();
  await init();
});
This ensures the token storage is properly configured before the first identity request is made.
You can find more details about the plugin loading order here - Plugin dependencies.