Skip to content

Commit

Permalink
Merge branch 'master' into browser
Browse files Browse the repository at this point in the history
  • Loading branch information
anshgoyalevil authored Aug 6, 2023
2 parents 0fb6787 + 5ff8192 commit f6ae27f
Show file tree
Hide file tree
Showing 16 changed files with 289 additions and 142 deletions.
2 changes: 1 addition & 1 deletion components/Hero.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import AlgoliaSearch, { SearchButton } from './AlgoliaSearch'; // Import Algolia
import IconLoupe from './icons/Loupe';
import {
useTranslation,
} from "next-i18next-static-site";
} from "../lib/i18n";

export default function Hero({ className = ''}) {

Expand Down
2 changes: 1 addition & 1 deletion components/link.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import Link from "next/link";
import { useRouter } from "next/router";
import { defaultLanguage, languages } from "next-i18next-static-site";
import { defaultLanguage, languages } from "../lib/i18n";

const LinkComponent = ({ children, locale, ...props }) => {
const router = useRouter();
Expand Down
2 changes: 1 addition & 1 deletion components/navigation/NavBar.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import {
defaultLanguage,
languages,
useTranslation,
} from "next-i18next-static-site";
} from "../../lib/i18n";
import browserLanguageDetector from "../../lib/browserLanguageDetector";

const isMobile = isMobileDevice();
Expand Down
4 changes: 2 additions & 2 deletions cypress/test/Hero.cy.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ describe('Hero Component', () => {
it('displays the correct content', () => {
mount(<Hero />);

cy.contains('Building the future of');
cy.contains('Event-Driven Architectures (EDA)');
cy.contains('main.header');
cy.contains('main.subHeader');
cy.contains('Open-Source tools to easily build and maintain your event-driven architecture.');
cy.contains('Read the docs');
cy.contains('Quick search...');
Expand Down
223 changes: 223 additions & 0 deletions lib/i18n.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,223 @@
import { useRouter } from "next/router";
import { useEffect, useState } from "react";
import Cookies from "js-cookie";
import i18next from "i18next";
import {
initReactI18next,
useTranslation,
withTranslation,
Translation,
Trans
} from "react-i18next";
import nextI18nextStaticSiteConfig from "../next-i18next-static-site.config";
var defaultConfig = {
allowHydration: true,
languages: ["en"],
defaultLanguage: "en",
namespaces: ["common"],
defaultNamespace: "common",
cookieName: "lang",
cookieOptions: { expires: 365, path: "/" }
};
var config = {
...defaultConfig,
languages: nextI18nextStaticSiteConfig.i18n.languages,
defaultLanguage: nextI18nextStaticSiteConfig.i18n.defaultLanguage,
namespaces: nextI18nextStaticSiteConfig.i18n.namespaces,
defaultNamespace: nextI18nextStaticSiteConfig.i18n.defaultNamespace
};

/**
* An array containing the supported language codes.
* @type {string[]}
*/
var languages = config.languages;
/**
* The default language code used for translation when no language is specified or available.
* @type {string}
*/
var defaultLanguage = config.defaultLanguage;
/**
* An array containing the supported namespaces for translation.
* @type {string[]}
*/
var namespaces = config.namespaces;
/**
* The default namespace used for translation when no namespace is specified or available.
* @type {string}
*/
var defaultNamespace = config.defaultNamespace;
/**
* A duplicate of the default namespace used for translation when no namespace is specified or available.
* @type {string}
*/
var defaultNamespace2 = config.defaultNamespace;
/**
* The name of the cookie used to store the user's preferred language.
* @type {string}
*/
var cookieName = config.cookieName;

/**
* Creates an i18next instance with the provided locales and language.
* @param {Object} locales - The locales object containing translations for different languages and namespaces.
* @param {string} language - The language code representing the desired language.
* @returns {Object} - The initialized i18next instance.
*/
var createI18nextInstance = (locales, language) => {
const plugins = [
initReactI18next
];
const i18nInstance = i18next;
plugins.map((plugin) => i18nInstance.use(plugin));
i18nInstance.init({
resources: locales,
cleanCode: true,
lng: language,
supportedLngs: config.languages,
fallbackLng: language ? language : config.defaultLanguage,
ns: config.namespaces,
defaultNS: config.defaultNamespace,
interpolation: {
escapeValue: false
},
react: {
useSuspense: false
},
load: "languageOnly"
});
return i18nInstance;
};

/**
* A global i18next instance used for translation.
* @type {?Object}
*/
var globalI18nextInstance = null;


/**
* Returns a singleton instance of the i18next object with the specified language and locales.
* If the instance doesn't exist, it creates a new one; otherwise, it changes the language of the existing instance.
* @param {string} language - The language code representing the desired language.
* @param {Object} locales - The locales object containing translations for different languages and namespaces.
* @returns {Object} - The i18next instance.
*/
var i18nextInstance = (language, locales) => {
if (!globalI18nextInstance) {
globalI18nextInstance = createI18nextInstance(locales, language);
return globalI18nextInstance;
} else {
globalI18nextInstance.changeLanguage(language);
return globalI18nextInstance;
}
};

/**
* A flag indicating whether the locales have been loaded.
* @type {boolean}
*/
var loaded = false;


/**
* A React component that provides i18n functionality to the child components.
* @param {Object} props - The props object containing the i18n options and child components.
* @returns {JSX.Element|null} - The child components wrapped in the i18n provider, or null if hydration is not allowed.
*/
var I18nProvider = (props) => {
var _a;
const [hydration, setHydration] = useState(false);
const options = { ...config, ...props.i18n };
if (!((_a = props.i18n) == null ? void 0 : _a.locales)) {
throw new Error("locales object was not passed into I18nProvider");
}
const router = useRouter();
const { asPath, query } = router;
const slug = asPath.split("/")[1];
const langSlug = config.languages.includes(slug) && slug;
const language = (query.lang || langSlug || config.defaultLanguage).toString();
const pathLocale = (query.lang || langSlug).toString();
if (pathLocale && pathLocale !== "false") {
Cookies.set(config.cookieName, pathLocale, config.cookieOptions);
}
if (!loaded) {
i18nextInstance(language, props.i18n.locales);
}
const { i18n: i18n2 } = useTranslation();
useEffect(() => {
i18n2.services.resourceStore.data = props.i18n.locales;
i18n2.changeLanguage(language);
}, [i18n2, language, props.i18n.locales]);
useEffect(() => {
loaded = true;
i18n2.changeLanguage(language);
}, [i18n2, language]);
useEffect(() => {
const hasWindow = typeof window !== "undefined";
if (hasWindow && options.allowHydration) {
setHydration(true);
}
}, [options.allowHydration]);
return hydration ? props.children : null;
};

/**
* Retrieves all language slugs for use in Next.js dynamic routing.
* @returns {Object[]} - An array of objects, each containing the "params" property with the "lang" parameter for each language.
*/
function getAllLanguageSlugs() {
return config.languages.map((lang) => {
return { params: { lang } };
});
}

/**
* Retrieves the valid language code based on the provided language.
* If the provided language is not valid, returns the default language.
* @param {string} lang - The language code to check for validity.
* @returns {string} - The valid language code.
*/
function getLanguage(lang) {
return config.languages.includes(lang) ? lang : config.defaultLanguage;
}

/**
* Detects the user's preferred language based on cookies and browser settings.
* If a preferred language is found, redirects the user to the corresponding language page.
*/
var languageDetection = () => {
const router = useRouter();
useEffect(() => {
let cookieLocale = Cookies.get(cookieName) || void 0;
let browserLocale = (navigator.languages && navigator.languages.length ? navigator.languages[0] : navigator.language) || void 0;
if (browserLocale) {
browserLocale = browserLocale.slice(0, 2);
}
if (cookieLocale && languages.includes(cookieLocale)) {
router.push("/" + cookieLocale);
} else if (browserLocale && languages.includes(browserLocale)) {
router.push("/" + browserLocale);
} else {
router.push("/" + defaultLanguage);
}
}, [router, defaultLanguage]);
return null;
};
export {
I18nProvider,
Trans,
Translation,
cookieName,
defaultLanguage,
defaultNamespace,
defaultNamespace2,
getAllLanguageSlugs,
getLanguage,
i18nextInstance,
languageDetection,
languages,
namespaces,
useTranslation,
withTranslation
};
2 changes: 1 addition & 1 deletion lib/locales.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { languages, namespaces } from "next-i18next-static-site";
import { languages, namespaces } from "../lib/i18n";

function loadLocales() {
// Load all locales, required for next-i18n-static-site
Expand Down
2 changes: 0 additions & 2 deletions netlify.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
[[edge_functions]]
function = "serve-definitions"
path = "/definitions/*"
cache = "manual"

# Used by JSON Schema definitions fetched from schemastore.org
[[redirects]]
Expand All @@ -34,7 +33,6 @@ cache = "manual"
[[edge_functions]]
function = "serve-definitions"
path = "/schema-store/*"
cache = "manual"

[[plugins]]
package = "@netlify/plugin-nextjs"
31 changes: 19 additions & 12 deletions netlify/edge-functions/serve-definitions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ const legitimateRequestRegex = /^\/[\w\-]*\/?(?:([\w\-\.]*\/)?([\w\-$%\.]*\.json

export default async (request: Request, context: Context) => {
let rewriteRequest = buildRewrite(request);

let response: Response;
if (rewriteRequest === null) {
rewriteRequest = request;
Expand All @@ -33,6 +32,12 @@ export default async (request: Request, context: Context) => {
const isRequestingAFile = request.url.endsWith('.json');
if (isRequestingAFile) {
var metricName: string
const metricAttributes = {
'responseStatus': response.status,
'responseStatusText': response.statusText,
'cached': false,
};

if (response.ok) {
// Manually cloning the response so we can modify the headers as they are immutable
response = new Response(response.body, response);
Expand All @@ -43,15 +48,18 @@ export default async (request: Request, context: Context) => {

metricName = "asyncapi.jsonschema.download.success";
} else {
// Notifying NR of the error.
metricName = "asyncapi.jsonschema.download.error";
switch (response.status) {
case 304:
metricName = "asyncapi.jsonschema.download.success";
metricAttributes["cached"] = true;
break;
default:
// Notifying NR of the error.
metricName = "asyncapi.jsonschema.download.error";
break;
}
}

const metricAttributes = {
"responseStatus": response.status,
"responseStatusText": response.statusText,
};

// Sending metrics to NR.
await sendMetricToNR(context, newNRMetricCount(metricName, request, rewriteRequest, metricAttributes));
}
Expand All @@ -76,12 +84,11 @@ function buildRewrite(originalRequest: Request): (Request | null) {
url = URL_DEST_DEFINITIONS + `/${definitionVersion}${file}`;
}

originalRequest.headers.set('Authorization', 'token ' + GITHUB_TOKEN);

return new Request(url, {
method: originalRequest.method,
headers: new Headers({
// Setting GH Token to increase GH rate limit to 5,000 req/h.
'Authorization': "token " + GITHUB_TOKEN,
}),
headers: originalRequest.headers,
});
}

Expand Down
10 changes: 2 additions & 8 deletions next.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ const gemoji = require('remark-gemoji-to-emoji');
const a11yEmoji = require('@fec/remark-a11y-emoji');
const slug = require('remark-slug');
const headingId = require('remark-heading-id');
const { i18n } = require("./next-i18next-static-site.config");

const withMDX = require('@next/mdx')({
extension: /\.mdx?$/,
Expand All @@ -21,9 +20,7 @@ const withMDX = require('@next/mdx')({
},
});

const withTM = require("next-transpile-modules")(["next-i18next-static-site"]);

module.exports = withTM(withMDX({
module.exports = withMDX({
pageExtensions: ['js', 'md'],
eslint: {
ignoreDuringBuilds: true,
Expand All @@ -39,7 +36,4 @@ module.exports = withTM(withMDX({

return config;
},
publicRuntimeConfig: {
i18n,
},
}));
});
Loading

0 comments on commit f6ae27f

Please sign in to comment.