Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

remix-i18next

Package Overview
Dependencies
Maintainers
1
Versions
43
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

remix-i18next - npm Package Compare versions

Comparing version 5.5.0 to 6.0.0-pre.1

.eslintrc.cjs

8

build/client.js

@@ -1,4 +0,1 @@

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.getInitialNamespaces = void 0;
/**

@@ -13,8 +10,7 @@ * Get the list of namespaces used by the application server-side so you could

*/
function getInitialNamespaces() {
export function getInitialNamespaces() {
let namespaces = new Set(Object.values(window.__remixRouteModules)
.filter((route) => { var _a; return ((_a = route.handle) === null || _a === void 0 ? void 0 : _a.i18n) !== undefined; })
.filter((route) => route.handle?.i18n !== undefined)
.flatMap((route) => route.handle.i18n));
return [...namespaces];
}
exports.getInitialNamespaces = getInitialNamespaces;

@@ -1,6 +0,3 @@

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.getClientLocales = void 0;
const intl_parse_accept_language_1 = require("intl-parse-accept-language");
function getClientLocales(requestOrHeaders) {
import { parseAcceptLanguage } from "intl-parse-accept-language";
export function getClientLocales(requestOrHeaders) {
let headers = getHeaders(requestOrHeaders);

@@ -11,3 +8,3 @@ let acceptLanguage = headers.get("Accept-Language");

return undefined;
let locales = (0, intl_parse_accept_language_1.parseAcceptLanguage)(acceptLanguage, {
let locales = parseAcceptLanguage(acceptLanguage, {
validate: Intl.DateTimeFormat.supportedLocalesOf,

@@ -25,3 +22,2 @@ ignoreWildcard: true,

}
exports.getClientLocales = getClientLocales;
/**

@@ -28,0 +24,0 @@ * Receives a Request or Headers objects.

@@ -1,4 +0,1 @@

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.getHeaders = void 0;
/**

@@ -9,3 +6,3 @@ * Receives a Request or Headers objects.

*/
function getHeaders(requestOrHeaders) {
export function getHeaders(requestOrHeaders) {
if (requestOrHeaders instanceof Request) {

@@ -16,2 +13,1 @@ return requestOrHeaders.headers;

}
exports.getHeaders = getHeaders;

@@ -1,2 +0,2 @@

/// <reference types="react" />
import * as React from "react";
export interface PreloadTranslationsProps {

@@ -15,3 +15,3 @@ loadPath: string;

*/
export declare function PreloadTranslations({ loadPath }: PreloadTranslationsProps): JSX.Element;
export declare function PreloadTranslations({ loadPath }: PreloadTranslationsProps): React.JSX.Element;
/**

@@ -18,0 +18,0 @@ * Get the locale returned by the root route loader under the `locale` key.

@@ -1,8 +0,4 @@

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.useChangeLanguage = exports.useLocale = exports.PreloadTranslations = void 0;
const jsx_runtime_1 = require("react/jsx-runtime");
const react_1 = require("@remix-run/react");
const react_2 = require("react");
const react_i18next_1 = require("react-i18next");
import { useMatches } from "@remix-run/react";
import * as React from "react";
import { useTranslation } from "react-i18next";
/**

@@ -18,17 +14,16 @@ * Preload the translations files for the current language and the namespaces

*/
function PreloadTranslations({ loadPath }) {
let { i18n } = (0, react_i18next_1.useTranslation)();
export function PreloadTranslations({ loadPath }) {
let { i18n } = useTranslation();
let namespaces = [
...new Set((0, react_1.useMatches)()
.filter((route) => { var _a; return ((_a = route.handle) === null || _a === void 0 ? void 0 : _a.i18n) !== undefined; })
...new Set(useMatches()
.filter((route) => route.handle?.i18n !== undefined)
.flatMap((route) => route.handle.i18n)),
];
let lang = i18n.language;
return ((0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: namespaces.map((namespace) => {
return ((0, jsx_runtime_1.jsx)("link", { rel: "preload", as: "fetch", href: loadPath
.replace("{{lng}}", lang)
.replace("{{ns}}", namespace) }, namespace));
}) }));
return (React.createElement(React.Fragment, null, namespaces.map((namespace) => {
return (React.createElement("link", { key: namespace, rel: "preload", as: "fetch", href: loadPath
.replace("{{lng}}", lang)
.replace("{{ns}}", namespace) }));
})));
}
exports.PreloadTranslations = PreloadTranslations;
/**

@@ -43,6 +38,5 @@ * Get the locale returned by the root route loader under the `locale` key.

*/
function useLocale(localeKey = "locale") {
var _a;
let [rootMatch] = (0, react_1.useMatches)();
let { [localeKey]: locale } = (_a = rootMatch.data) !== null && _a !== void 0 ? _a : {};
export function useLocale(localeKey = "locale") {
let [rootMatch] = useMatches();
let { [localeKey]: locale } = rootMatch.data ?? {};
if (!locale)

@@ -54,3 +48,2 @@ throw new Error("Missing locale returned by the root loader.");

}
exports.useLocale = useLocale;
/**

@@ -61,8 +54,7 @@ * Detect when the locale returned by the root route loader changes and call

*/
function useChangeLanguage(locale) {
let { i18n } = (0, react_i18next_1.useTranslation)();
(0, react_2.useEffect)(() => {
export function useChangeLanguage(locale) {
let { i18n } = useTranslation();
React.useEffect(() => {
i18n.changeLanguage(locale);
}, [locale, i18n]);
}
exports.useChangeLanguage = useChangeLanguage;

@@ -1,9 +0,8 @@

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.RemixI18Next = void 0;
const accept_language_parser_1 = require("accept-language-parser");
const i18next_1 = require("i18next");
const get_client_locales_1 = require("./lib/get-client-locales");
import { pick } from "accept-language-parser";
import { createInstance, } from "i18next";
import { getClientLocales } from "./lib/get-client-locales.js";
const DEFAULT_NS = "translation";
class RemixI18Next {
export class RemixI18Next {
options;
detector;
constructor(options) {

@@ -40,3 +39,3 @@ this.options = options;

let namespaces = Object.values(context.routeModules)
.filter((route) => { var _a; return ((_a = route.handle) === null || _a === void 0 ? void 0 : _a.i18n) !== undefined; })
.filter((route) => route.handle?.i18n !== undefined)
.flatMap((route) => {

@@ -55,7 +54,6 @@ let i18n = route.handle.i18n;

async getFixedT(requestOrLocale, namespaces, options = {}) {
var _a;
let parsedNamespaces = namespaces !== null && namespaces !== void 0 ? namespaces : DEFAULT_NS;
let parsedNamespaces = namespaces ?? DEFAULT_NS;
// Make sure there's at least one namespace
if (!namespaces || namespaces.length === 0) {
parsedNamespaces = (((_a = this.options.i18next) === null || _a === void 0 ? void 0 : _a.defaultNS) ||
parsedNamespaces = (this.options.i18next?.defaultNS ||
"translation");

@@ -81,3 +79,3 @@ }

async createInstance(options = {}) {
let instance = (0, i18next_1.createInstance)();
let instance = createInstance();
let plugins = [

@@ -93,4 +91,4 @@ ...(this.options.backend ? [this.options.backend] : []),

}
exports.RemixI18Next = RemixI18Next;
class LanguageDetector {
options;
constructor(options) {

@@ -102,4 +100,3 @@ this.options = options;

isSessionOnly(options) {
var _a;
if (((_a = options.order) === null || _a === void 0 ? void 0 : _a.length) === 1 &&
if (options.order?.length === 1 &&
options.order[0] === "session" &&

@@ -111,4 +108,3 @@ !options.sessionStorage) {

isCookieOnly(options) {
var _a;
if (((_a = options.order) === null || _a === void 0 ? void 0 : _a.length) === 1 &&
if (options.order?.length === 1 &&
options.order[0] === "cookie" &&

@@ -120,4 +116,3 @@ !options.cookie) {

async detect(request) {
var _a;
let order = (_a = this.options.order) !== null && _a !== void 0 ? _a : [
let order = this.options.order ?? [
"searchParams",

@@ -148,15 +143,13 @@ "cookie",

async fromSearchParams(request) {
var _a, _b;
let url = new URL(request.url);
if (!url.searchParams.has((_a = this.options.searchParamKey) !== null && _a !== void 0 ? _a : "lng")) {
if (!url.searchParams.has(this.options.searchParamKey ?? "lng")) {
return null;
}
return this.fromSupported(url.searchParams.get((_b = this.options.searchParamKey) !== null && _b !== void 0 ? _b : "lng"));
return this.fromSupported(url.searchParams.get(this.options.searchParamKey ?? "lng"));
}
async fromCookie(request) {
var _a;
if (!this.options.cookie)
return null;
let cookie = this.options.cookie;
let lng = (_a = (await cookie.parse(request.headers.get("Cookie")))) !== null && _a !== void 0 ? _a : "";
let lng = (await cookie.parse(request.headers.get("Cookie"))) ?? "";
if (!lng)

@@ -167,7 +160,6 @@ return null;

async fromSessionStorage(request) {
var _a;
if (!this.options.sessionStorage)
return null;
let session = await this.options.sessionStorage.getSession(request.headers.get("Cookie"));
let lng = session.get((_a = this.options.sessionKey) !== null && _a !== void 0 ? _a : "lng");
let lng = session.get(this.options.sessionKey ?? "lng");
if (!lng)

@@ -178,3 +170,3 @@ return null;

async fromHeader(request) {
let locales = (0, get_client_locales_1.getClientLocales)(request);
let locales = getClientLocales(request);
if (!locales)

@@ -187,5 +179,5 @@ return null;

fromSupported(language) {
return ((0, accept_language_parser_1.pick)(this.options.supportedLanguages, language !== null && language !== void 0 ? language : this.options.fallbackLanguage, { loose: false }) ||
(0, accept_language_parser_1.pick)(this.options.supportedLanguages, language !== null && language !== void 0 ? language : this.options.fallbackLanguage, { loose: true }));
return (pick(this.options.supportedLanguages, language ?? this.options.fallbackLanguage, { loose: false }) ||
pick(this.options.supportedLanguages, language ?? this.options.fallbackLanguage, { loose: true }));
}
}
{
"name": "remix-i18next",
"version": "5.5.0",
"version": "6.0.0-pre.1",
"description": "The easiest way to translate your Remix apps",
"license": "MIT",
"sideEffects": false,
"browser": {
"./build": "./browser",
"./build/backend": false
"homepage": "https://github.com/sergiodxa/remix-i18next#readme",
"engines": {
"node": ">=18.0.0"
},
"main": "./build/index.js",
"types": "./build/index.d.ts",
"jsnext:main": "./browser/index.js",
"module": "./browser/index.js",
"type": "module",
"exports": {
"./package.json": "./package.json",
".": {
"types": "./build/index.d.ts",
"import": "./browser/index.js",
"require": "./build/index.js"
}
"./client": "./build/client.js",
"./server": "./build/server.js",
"./react": "./build/react.js"
},
"sideEffects": false,
"scripts": {
"prepare": "npm run build",
"build": "npm run build:browser && npm run build:main",
"build:browser": "tsc --project tsconfig.json --module ESNext --outDir ./browser",
"build:main": "tsc --project tsconfig.json --module CommonJS --outDir ./build",
"build": "tsc --project tsconfig.json --outDir ./build",
"format": "prettier --write \"src/**/*.ts\" \"src/**/*.tsx\" \"test/**/*.ts\" \"test/**/*.tsx\" \"*.md\" \"package.json\"",
"typecheck": "tsc --project tsconfig.json --noEmit",
"lint": "eslint --ext .ts,.tsx src/",
"test": "vitest"
"test": "vitest --run",
"test:watch": "vitest",
"test:coverage": "vitest --coverage",
"test:exports": "bun scripts/check-pkg-exports.ts"
},
"author": {
"name": "Sergio Xalambrí",
"url": "https://sergiodxa.com",
"email": "hello@sergiodxa.com"
},
"repository": {

@@ -36,2 +38,5 @@ "type": "git",

},
"bugs": {
"url": "https://github.com/sergiodxa/remix-i18next/issues"
},
"keywords": [

@@ -44,14 +49,12 @@ "remix",

],
"author": {
"name": "Sergio Xalambrí",
"email": "hello@sergiodxa.com",
"url": "https://sergiodxa.com"
"dependencies": {
"accept-language-parser": "^1.5.0",
"intl-parse-accept-language": "^1.0.0",
"use-consistent-value": "^1.0.0"
},
"bugs": {
"url": "https://github.com/sergiodxa/remix-i18next/issues"
},
"homepage": "https://github.com/sergiodxa/remix-i18next#readme",
"peerDependencies": {
"@remix-run/react": "^1.0.0 || ^2.0.0",
"@remix-run/server-runtime": "^1.0.0 || ^2.0.0",
"@remix-run/cloudflare": "^2.0.0",
"@remix-run/deno": "^2.0.0",
"@remix-run/node": "^2.0.0",
"@remix-run/react": "^2.0.0",
"i18next": "^23.1.0",

@@ -61,36 +64,49 @@ "react": "^16.8.0 || ^17.0.0 || ^18.0.0",

},
"dependencies": {
"accept-language-parser": "^1.5.0",
"intl-parse-accept-language": "^1.0.0",
"lru-cache": "^7.14.1",
"use-consistent-value": "^1.0.0"
"peerDependenciesMeta": {
"@remix-run/cloudflare": {
"optional": true
},
"@remix-run/deno": {
"optional": true
},
"@remix-run/node": {
"optional": true
}
},
"devDependencies": {
"@remix-run/dev": "^2.0.0",
"@remix-run/node": "^2.0.0",
"@remix-run/react": "^2.0.0",
"@remix-run/server-runtime": "^2.0.0",
"@types/accept-language-parser": "^1.5.3",
"@types/node": "^18.11.9",
"@types/prop-types": "^15.7.5",
"@types/react": "^18.0.25",
"@typescript-eslint/eslint-plugin": "^5.62.0",
"@typescript-eslint/parser": "^5.62.0",
"eslint": "^8.28.0",
"eslint-config-prettier": "^8.5.0",
"eslint-plugin-cypress": "^2.12.1",
"eslint-plugin-import": "^2.26.0",
"eslint-plugin-jest-dom": "^4.0.3",
"eslint-plugin-prettier": "^4.2.1",
"@arethetypeswrong/cli": "^0.14.1",
"@remix-run/cloudflare": "^2.7.2",
"@remix-run/deno": "^2.7.2",
"@remix-run/dev": "^2.7.2",
"@remix-run/node": "^2.7.2",
"@remix-run/react": "^2.7.2",
"@remix-run/server-runtime": "^2.7.2",
"@types/accept-language-parser": "^1.5.6",
"@types/bun": "^1.0.7",
"@types/node": "^20.11.20",
"@types/prop-types": "^15.7.11",
"@types/react": "^18.2.58",
"@typescript-eslint/eslint-plugin": "^7.0.2",
"@typescript-eslint/parser": "^7.0.2",
"eslint": "^8.56.0",
"eslint-config-prettier": "^9.1.0",
"eslint-import-resolver-typescript": "^3.6.1",
"eslint-plugin-import": "^2.29.1",
"eslint-plugin-jest-dom": "^5.1.0",
"eslint-plugin-jsx-a11y": "^6.8.0",
"eslint-plugin-prettier": "^5.1.3",
"eslint-plugin-promise": "^6.1.1",
"eslint-plugin-testing-library": "^5.9.1",
"eslint-plugin-unicorn": "^45.0.0",
"i18next": "^23.1.0",
"prettier": "^2.8.8",
"eslint-plugin-react": "^7.33.2",
"eslint-plugin-react-hooks": "^4.6.0",
"eslint-plugin-testing-library": "^6.2.0",
"eslint-plugin-unicorn": "^51.0.1",
"i18next": "^23.10.0",
"lru-cache": "^10.2.0",
"prettier": "^3.2.5",
"react": "^18.2.0",
"react-i18next": "^14.0.0",
"ts-node": "^10.9.1",
"typescript": "^5.1.0",
"vitest": "^0.25.3"
"react-i18next": "^14.0.5",
"ts-node": "^10.9.2",
"typescript": "^5.3.3",
"vitest": "^1.3.1"
}
}

@@ -161,4 +161,6 @@ # remix-i18next

import { PassThrough } from "stream";
import type { EntryContext } from "@remix-run/node";
import { Response } from "@remix-run/node";
import {
createReadableStreamFromReadable,
type EntryContext,
} from '@remix-run/node';
import { RemixServer } from "@remix-run/react";

@@ -210,7 +212,7 @@ import isbot from "isbot";

let body = new PassThrough();
const stream = createReadableStreamFromReadable(body);
responseHeaders.set("Content-Type", "text/html");
resolve(
new Response(body, {
new Response(stream, {
headers: responseHeaders,

@@ -290,3 +292,3 @@ status: didError ? 500 : responseStatusCode,

> **Warning** In latest versions you may find an error with `useChangeLanguage` hook, (see [#107](https://github.com/sergiodxa/remix-i18next/issues/107)), to solve it, copy the code of `useChangeLanguage` to your own app and use it instead of the one provided by `remix-i18next`.
> **Warning** In latest versions you may find an error with `useChangeLanguage` hook, (see [#107](https://github.com/sergiodxa/remix-i18next/issues/107)), to solve it, you can deep import it from the package with `import { useChangeLanguage } from 'node_modules/remix-i18next/browser/react';`, or copy the code of `useChangeLanguage` to your own app and use it instead of the one provided by `remix-i18next`.

@@ -293,0 +295,0 @@ ```ts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc