nuxt-i18n-micro 1.1.1 → 1.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,5 +1,3 @@
1
- # Nuxt I18n Micro
2
-
3
1
  <div class="links">
4
2
  <a href="https://www.npmjs.com/package/nuxt-i18n-micro" target="_blank">
5
3
  <img src="https://img.shields.io/npm/v/nuxt-i18n-micro/latest?style=for-the-badge" alt="npm version">
@@ -15,6 +13,12 @@
15
13
  </a>
16
14
  </div>
17
15
 
16
+ <p align="center">
17
+ <img src="https://github.com/s00d/nuxt-i18n-micro/blob/main/logo.png?raw=true" alt="logo">
18
+ </p>
19
+
20
+ # Nuxt I18n Micro
21
+
18
22
  `Nuxt I18n Micro` is a fast, simple, and lightweight internationalization (i18n) module for Nuxt. Despite its compact size, it's designed with large projects in mind, offering significant performance improvements over traditional i18n solutions like `nuxt-i18n`. The module was built from the ground up to be highly efficient, focusing on minimizing build times, reducing server load, and shrinking bundle sizes.
19
23
 
20
24
  ## Why Nuxt I18n Micro?
@@ -8,4 +8,4 @@
8
8
  <link rel="prefetch" as="style" href="/__nuxt-i18n-micro/_nuxt/error-500.B4KzowuE.css">
9
9
  <link rel="prefetch" as="script" crossorigin href="/__nuxt-i18n-micro/_nuxt/HZLiFEh-.js">
10
10
  <script type="module" src="/__nuxt-i18n-micro/_nuxt/6EJ4fAZ2.js" crossorigin></script></head><body><div id="__nuxt"></div><div id="teleports"></div><script type="application/json" id="__NUXT_DATA__" data-ssr="false">[{"serverRendered":1},false]</script>
11
- <script>window.__NUXT__={};window.__NUXT__.config={public:{},app:{baseURL:"/__nuxt-i18n-micro",buildId:"c53d284f-1ca1-4e93-bf70-990155baabf5",buildAssetsDir:"/_nuxt/",cdnURL:""}}</script></body></html>
11
+ <script>window.__NUXT__={};window.__NUXT__.config={public:{},app:{baseURL:"/__nuxt-i18n-micro",buildId:"29fcfc53-dd00-4f63-aad8-54e96d19e2cd",buildAssetsDir:"/_nuxt/",cdnURL:""}}</script></body></html>
@@ -8,4 +8,4 @@
8
8
  <link rel="prefetch" as="style" href="/__nuxt-i18n-micro/_nuxt/error-500.B4KzowuE.css">
9
9
  <link rel="prefetch" as="script" crossorigin href="/__nuxt-i18n-micro/_nuxt/HZLiFEh-.js">
10
10
  <script type="module" src="/__nuxt-i18n-micro/_nuxt/6EJ4fAZ2.js" crossorigin></script></head><body><div id="__nuxt"></div><div id="teleports"></div><script type="application/json" id="__NUXT_DATA__" data-ssr="false">[{"serverRendered":1},false]</script>
11
- <script>window.__NUXT__={};window.__NUXT__.config={public:{},app:{baseURL:"/__nuxt-i18n-micro",buildId:"c53d284f-1ca1-4e93-bf70-990155baabf5",buildAssetsDir:"/_nuxt/",cdnURL:""}}</script></body></html>
11
+ <script>window.__NUXT__={};window.__NUXT__.config={public:{},app:{baseURL:"/__nuxt-i18n-micro",buildId:"29fcfc53-dd00-4f63-aad8-54e96d19e2cd",buildAssetsDir:"/_nuxt/",cdnURL:""}}</script></body></html>
@@ -1 +1 @@
1
- {"id":"c53d284f-1ca1-4e93-bf70-990155baabf5","timestamp":1723869304838}
1
+ {"id":"29fcfc53-dd00-4f63-aad8-54e96d19e2cd","timestamp":1723887203026}
@@ -0,0 +1 @@
1
+ {"id":"29fcfc53-dd00-4f63-aad8-54e96d19e2cd","timestamp":1723887203026,"matcher":{"static":{},"wildcard":{},"dynamic":{}},"prerendered":[]}
@@ -8,4 +8,4 @@
8
8
  <link rel="prefetch" as="style" href="/__nuxt-i18n-micro/_nuxt/error-500.B4KzowuE.css">
9
9
  <link rel="prefetch" as="script" crossorigin href="/__nuxt-i18n-micro/_nuxt/HZLiFEh-.js">
10
10
  <script type="module" src="/__nuxt-i18n-micro/_nuxt/6EJ4fAZ2.js" crossorigin></script></head><body><div id="__nuxt"></div><div id="teleports"></div><script type="application/json" id="__NUXT_DATA__" data-ssr="false">[{"serverRendered":1},false]</script>
11
- <script>window.__NUXT__={};window.__NUXT__.config={public:{},app:{baseURL:"/__nuxt-i18n-micro",buildId:"c53d284f-1ca1-4e93-bf70-990155baabf5",buildAssetsDir:"/_nuxt/",cdnURL:""}}</script></body></html>
11
+ <script>window.__NUXT__={};window.__NUXT__.config={public:{},app:{baseURL:"/__nuxt-i18n-micro",buildId:"29fcfc53-dd00-4f63-aad8-54e96d19e2cd",buildAssetsDir:"/_nuxt/",cdnURL:""}}</script></body></html>
package/dist/module.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "nuxt-i18n-micro",
3
3
  "configKey": "i18n",
4
- "version": "1.1.1",
4
+ "version": "1.1.2",
5
5
  "builder": {
6
6
  "@nuxt/module-builder": "0.8.3",
7
7
  "unbuild": "2.0.0"
package/dist/module.mjs CHANGED
@@ -1,7 +1,7 @@
1
1
  import path from 'node:path';
2
2
  import * as fs from 'node:fs';
3
3
  import { existsSync, mkdirSync, writeFileSync } from 'node:fs';
4
- import { useNuxt, defineNuxtModule, createResolver, addPlugin, extendPages, addTypeTemplate } from '@nuxt/kit';
4
+ import { useNuxt, defineNuxtModule, createResolver, addPlugin, addServerHandler, extendPages, addTypeTemplate } from '@nuxt/kit';
5
5
  import { onDevToolsInitialized, extendServerRpc } from '@nuxt/devtools-kit';
6
6
 
7
7
  const DEVTOOLS_UI_PORT = 3030;
@@ -122,9 +122,9 @@ const module = defineNuxtModule({
122
122
  });
123
123
  }
124
124
  if (options.includeDefaultLocaleRoute) {
125
- addPlugin({
126
- src: resolver.resolve("./runtime/05.default-locale-redirect"),
127
- order: 4
125
+ addServerHandler({
126
+ middleware: true,
127
+ handler: resolver.resolve("./runtime/server/middleware/i18n-redirect.ts")
128
128
  });
129
129
  }
130
130
  const localeRegex = options.locales.filter((locale) => locale.code !== options.defaultLocale || options.includeDefaultLocaleRoute).map((locale) => locale.code).join("|");
@@ -199,6 +199,23 @@ const module = defineNuxtModule({
199
199
  }
200
200
  }
201
201
 
202
+ declare module 'vue/types/vue' {
203
+ interface Vue {
204
+ $getLocale: () => string;
205
+ $getLocales: () => string[];
206
+ $t: <T extends Record<string, string | number | boolean>>(
207
+ key: string,
208
+ params?: T,
209
+ defaultValue?: string
210
+ ) => string | number | boolean | Translations | PluralTranslations | unknown[] | unknown | null;
211
+ $tc: (key: string, count: number, defaultValue?: string) => string;
212
+ $mergeTranslations: (newTranslations: Translations) => void;
213
+ $switchLocale: (locale: string) => void;
214
+ $localeRoute: (to: RouteLocationRaw, locale?: string) => RouteLocationRaw;
215
+ $loadPageTranslations: (locale: string, routeName: string) => Promise<void>;
216
+ }
217
+ }
218
+
202
219
  export {};
203
220
  `;
204
221
  }
@@ -70,19 +70,15 @@ function switchLocale(locale, route, router, i18nConfig) {
70
70
  function getLocalizedRoute(to, router, route, i18nConfig, locale) {
71
71
  const { defaultLocale } = i18nConfig;
72
72
  const currentLocale = (locale || route.params.locale || defaultLocale).toString();
73
- let resolvedRoute = router.resolve(to);
74
- if (typeof to === "object" && "name" in to) {
75
- resolvedRoute = router.resolve({ name: to.name, params: to.params, query: to.query, hash: to.hash });
76
- delete resolvedRoute.params.locale;
77
- if (resolvedRoute.name) {
78
- const routeName = resolvedRoute.name.replace(`localized-`, "");
79
- resolvedRoute.name = currentLocale !== defaultLocale || i18nConfig.includeDefaultLocaleRoute ? `localized-${routeName}` : routeName;
80
- if (defaultLocale !== currentLocale || i18nConfig.includeDefaultLocaleRoute) {
81
- resolvedRoute.params.locale = currentLocale;
82
- }
83
- }
73
+ const selectRoute = router.resolve(to);
74
+ const routeName = selectRoute.name.replace(`localized-`, "");
75
+ const newRouteName = currentLocale !== defaultLocale || i18nConfig.includeDefaultLocaleRoute ? `localized-${routeName}` : routeName;
76
+ const newParams = { ...route.params };
77
+ delete newParams.locale;
78
+ if (currentLocale !== defaultLocale || i18nConfig.includeDefaultLocaleRoute) {
79
+ newParams.locale = currentLocale;
84
80
  }
85
- return resolvedRoute;
81
+ return router.resolve({ name: newRouteName, params: newParams });
86
82
  }
87
83
  export default defineNuxtPlugin(async (_nuxtApp) => {
88
84
  const router = useRouter();
@@ -0,0 +1,2 @@
1
+ declare const _default: import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<void>>;
2
+ export default _default;
@@ -0,0 +1,17 @@
1
+ import { defineEventHandler, sendRedirect } from "h3";
2
+ import { useRuntimeConfig } from "#imports";
3
+ export default defineEventHandler(async (event) => {
4
+ const config = useRuntimeConfig();
5
+ const i18nConfig = config.public.i18nConfig;
6
+ if (!i18nConfig.defaultLocale) {
7
+ throw new Error("defaultLocale is not defined in the module configuration");
8
+ }
9
+ const locales = i18nConfig.locales || [];
10
+ const pathParts = event.path.split("/").filter(Boolean);
11
+ const localeCode = pathParts[0];
12
+ const locale = locales.find((loc) => loc.code === localeCode);
13
+ if (!locale) {
14
+ const newPath = `/${i18nConfig.defaultLocale}/${pathParts.join("/")}`;
15
+ return sendRedirect(event, newPath, 301);
16
+ }
17
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nuxt-i18n-micro",
3
- "version": "1.1.1",
3
+ "version": "1.1.2",
4
4
  "description": "Nuxt I18n Micro is a lightweight, high-performance internationalization module for Nuxt, designed to handle multi-language support with minimal overhead, fast build times, and efficient runtime performance.",
5
5
  "repository": "s00d/nuxt-i18n-micro",
6
6
  "license": "MIT",
@@ -47,7 +47,7 @@
47
47
  "release": "npm run lint && npm run test && npm run prepack && changelogen --release && npm publish && git push --follow-tags",
48
48
  "lint": "eslint .",
49
49
  "lint:fix": "eslint . --fix",
50
- "test": "vitest run",
50
+ "test": "playwright test",
51
51
  "test:watch": "vitest watch",
52
52
  "test:types": "vue-tsc --noEmit && cd playground && vue-tsc --noEmit",
53
53
  "client:build": "nuxi generate client",
@@ -67,11 +67,12 @@
67
67
  "@nuxt/module-builder": "^0.8.3",
68
68
  "@nuxt/schema": "^3.12.4",
69
69
  "@nuxt/test-utils": "^3.14.1",
70
+ "@playwright/test": "^1.46.1",
70
71
  "@types/node": "^20.14.11",
71
72
  "changelogen": "^0.5.5",
72
73
  "eslint": "^9.7.0",
73
- "nuxt": "^3.12.4",
74
74
  "execa": "^9.3.0",
75
+ "nuxt": "^3.12.4",
75
76
  "typescript": "latest",
76
77
  "vitest": "^2.0.3",
77
78
  "vue-tsc": "^2.0.26"
@@ -1 +0,0 @@
1
- {"id":"c53d284f-1ca1-4e93-bf70-990155baabf5","timestamp":1723869304838,"matcher":{"static":{},"wildcard":{},"dynamic":{}},"prerendered":[]}
@@ -1,2 +0,0 @@
1
- declare const _default: import("#app").Plugin<Record<string, unknown>> & import("#app").ObjectPlugin<Record<string, unknown>>;
2
- export default _default;
@@ -1,28 +0,0 @@
1
- import { defineNuxtPlugin, navigateTo } from "#app";
2
- import { useRoute, useRouter, watch, computed } from "#imports";
3
- export default defineNuxtPlugin(async ({ $config }) => {
4
- const i18nConfig = $config.public.i18nConfig;
5
- const router = useRouter();
6
- const route = useRoute();
7
- if (!route.params?.locale) {
8
- const routeName = route.name;
9
- const newRouteName = `localized-${routeName}`;
10
- const newParams = { ...route.params, locale: i18nConfig.defaultLocale };
11
- if (import.meta.client) {
12
- location.href = router.resolve({ name: newRouteName, params: newParams }).href;
13
- } else {
14
- await navigateTo({ name: newRouteName, params: newParams }, { redirectCode: 301 });
15
- }
16
- }
17
- if (import.meta.client) {
18
- const routeName = computed(() => route.name);
19
- watch(routeName, async () => {
20
- if (!route.params?.locale) {
21
- const routeName2 = route.name;
22
- const newRouteName = `localized-${routeName2}`;
23
- const newParams = { ...route.params, locale: i18nConfig.defaultLocale };
24
- await navigateTo({ name: newRouteName, params: newParams }, { redirectCode: 301 });
25
- }
26
- });
27
- }
28
- });