Skip to content

next-intl: createNextIntlPlugin fails without next installed #202

@southpolesteve

Description

@southpolesteve

Problem

next-intl's createNextIntlPlugin (the standard way to configure next-intl in next.config.ts) internally tries to detect the installed Next.js version. In vinext projects where next isn't installed as a real package, this throws:

Failed to load next.config.ts: Failed to get current Next.js version.
This can happen if next-intl/plugin is imported into your app code outside of your next.config.js.

The config loading fails silently, the webpack alias (next-intl/config -> user's i18n/request.ts) never gets registered, and at runtime the app crashes with:

Error: Couldn't find next-intl config file

Context

PR #196 adds extractWebpackAliases, which correctly extracts webpack resolve.alias entries from next.config plugins. The mechanism works. The problem is upstream: createNextIntlPlugin crashes before it can set up the webpack function.

Current workaround

Users can set the webpack alias manually in next.config.ts instead of using createNextIntlPlugin:

import path from "node:path";
import { fileURLToPath } from "node:url";

const __dirname = path.dirname(fileURLToPath(import.meta.url));

export default {
  webpack: (config) => {
    config.resolve.alias["next-intl/config"] = path.resolve(__dirname, "i18n/request.ts");
    return config;
  },
};

This is what the test fixture uses (see tests/fixtures/ecosystem/next-intl/next.config.ts).

Possible solutions

  1. Shim next/package.json so that createNextIntlPlugin's version check succeeds. This is the least invasive fix, vinext already shims many next/* imports.

  2. Catch and retry config loading when the webpack function extraction fails due to a missing next package, and provide a helpful error message pointing users to the manual alias workaround.

  3. Auto-detect next-intl in package.json dependencies and register the next-intl/config alias automatically (probe for i18n/request.{ts,tsx,js,jsx} in standard locations). This would make next-intl work zero-config without needing createNextIntlPlugin at all.

  4. Engage with next-intl upstream to make the version check optional or graceful when next isn't found, so the plugin works in alternative frameworks.

Additional note: requestLocale is always undefined

Separately from the config loading issue, getRequestConfig's requestLocale parameter is always undefined in vinext. In Next.js, this is populated by next-intl's middleware. Users need to explicitly pass { locale } to getMessages() and use client components with NextIntlClientProvider for locale-aware rendering. Server-side useTranslations without explicit locale passing will always fall back to the default locale.

This is tracked implicitly by the "partial" support status for next-intl but is worth calling out for anyone working on deeper integration.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions