diff --git a/README.md b/README.md index 869121a..6450873 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,7 @@ # NEXT.js Static Page Localizer -# WARNING !!! Currently broken. Working on fix - -### Introdduction +### Introduction This is a package for creating localized NEXT.js applications that runs as Static Web Pages. While static web pages are cheap, easy to use and great, they lack some functionality to support some of the more poular localization packages. @@ -19,7 +17,9 @@ npm i nextjs-static-page-localizer ## Add required files -At your root you need to create a folder called `messages` and this should contain a file called `config.json` and a `.json` file for each language you aim to support. +While technically you don't need to add extra files to your project for this, it is advisable to do so in order to keep your project more easily navigable, maintainable and easier to work with. Following from here, we will use our prefered way of setting this up, which closely resembles the way in which other localization/internationalization packages use. + +At your root you need to create a folder called `messages` and this should contain a file called `config.json` and a `.json` file for each language you aim to support. ### Configure config.json @@ -128,6 +128,73 @@ Given that we want to have support for the languages English and Spanish, a setu } ``` +### Set up wrapper + +In order for using the language files you've just created and make their contents available in all of your sub-modules, you need to initialize a wrapper in your `layout.tsx` file. + +```ts +import './globals.css' +// Import the wrapper and the Configuration class +import { LocalizerWrapper, Configuration } from 'nextjs-static-page-localizer' + +// Load the configuration +const config = require('@/messages/config') + +// Set up the default title and description +export const metadata = { + title: 'Default Title', + description: 'Default description', +} + +export default async function RootLayout({ + children, + params +}: { + children: React.ReactNode, + params: any +}) { + + // Create the configuration object based on the loaded configuration + const configuration = new Configuration(config.default, config.languages, config.messages) + + // Wrap the main section with the wrapper and pass in the configuration + return ( + + + +
+ {children} +
+
+ + + ) +} + +``` + +For this we created an additional file in the messages folder to keep the code at the layout element cleaner, `config.js`, which loads the data from the files fo us. You could do the same or load the data in a similar manner directly to your layout element. + +```ts +const config = require('./config.json'); + +const en = require('./en.json'); +const no = require('./no.json'); +const cs = require('./cs.json'); + +const messages = { + "en": en, + "no": no, + "cs": cs +} + +module.exports = { + default: config.default, + languages: config.languages, + messages: messages +} +``` + ### Using the content in components So far we've talked about how to create the structure. Now we will talk about how to use the content in our app. @@ -161,7 +228,7 @@ function YourComponent(){ export default YourComponent ``` -#### Using HTML language setter +### Using HTML language setter This package also support setting the `lang` section of the root `HTML` element. We will now add this to the code we made previously. This is quite easy to do, and it will specify the language as of the `?lang=` section of the url. If it does not find this, it will specify the default language as the language of the page. @@ -189,7 +256,7 @@ function YourComponent(){ export default YourComponent ``` -#### Specifying page metadata +### Specifying page metadata In order to make even the title and description localized we can use the metadata setter to set the content of the header title and description as we have specified in our language files. @@ -218,4 +285,82 @@ function YourComponent(){ export default YourComponent -``` \ No newline at end of file +``` + + +### Create a Link to other sub-pages + +In your project you probably wither have, or will at some point need to have some sub-pages. When you have that you'll need some way to navigate between the pages. Given that we are using a query parameter for determining the prefered language this needs to be part of the link as your're going from one sub-page to another without loosing the setting. + +We have for this purpose created a link element that builds on the NEXT.js Link element, which handles this language setting for you. Under is an example of how that can be set up. + +```ts +'use client' +// Import the translationsfetcher +import { useTranslationsFetcher } from "nextjs-static-page-localizer"; +// Import the LocalizedLink component +import { LocalizedLink } from "nextjs-static-page-localizer/components"; + +export default function Header() { + // Import the translations so that the links can have localized Labels as well + const tranlations = useTranslationsFetcher(); + // Get the section in which you have the link names (not neccesarily the same as this) + const link_names = tranlations("links"); + + // Create the link elements + return ( +
+
+ link_names("home") + link_names("about") +
+
+ ); +} +``` + +### Create a Language Switcher + +Now we'll also have to have a way to set the language so that the user can switch the language the page is in. We have also created a component that switches the languages while not changing the page that one currently is on. We will now expand on the last example to add the language setters. Here we'll do it dynamically based on the languages we have in our config, however you can create each component by it self if you wish to do so. + +```ts +'use client' +// Import the language interface +import { Language } from "nextjs-static-page-localizer/interfaces"; +// Import the useLocalization +import { useTranslationsFetcher, useLocalization } from "nextjs-static-page-localizer"; +// Import the LanguageSwitcher component +import { LocalizedLink, LanguageSwitcher } from "nextjs-static-page-localizer/components"; + +export default function Header() { + // Fetch the configuration + const { configuration } = useLocalization(); + const tranlations = useTranslationsFetcher(); + const link_names = tranlations("links"); + + // Create a component for each language dynamically based on the languages + return ( +
+
+ { + configuration.languages.map((language:Language) => { + return ( + +

{language.name}

+
+ ); + }) + } +
+
+

link_names("home")

+

link_names("about")

+
+
+ ); +} +``` + diff --git a/components.d.ts b/components.d.ts new file mode 100644 index 0000000..694d678 --- /dev/null +++ b/components.d.ts @@ -0,0 +1,2 @@ +export { default as LanguageSwitcher } from "./dist/components/LanguageSwitcher"; +export { default as LocalizedLink } from "./dist/components/LocalizedLink"; diff --git a/components.js b/components.js new file mode 100644 index 0000000..178448d --- /dev/null +++ b/components.js @@ -0,0 +1,2 @@ +export { default as LanguageSwitcher } from "./dist/components/LanguageSwitcher"; +export { default as LocalizedLink } from "./dist/components/LocalizedLink"; \ No newline at end of file diff --git a/interfaces.d.ts b/interfaces.d.ts new file mode 100644 index 0000000..ee6d33d --- /dev/null +++ b/interfaces.d.ts @@ -0,0 +1,3 @@ +export * from "./dist/interfaces/ConfigurationInterface"; +export * from "./dist/interfaces/Language"; +export * from "./dist/interfaces/Messages"; diff --git a/interfaces.js b/interfaces.js new file mode 100644 index 0000000..ed81156 --- /dev/null +++ b/interfaces.js @@ -0,0 +1,3 @@ +export * from "./dist/interfaces/ConfigurationInterface"; +export * from "./dist/interfaces/Language"; +export * from "./dist/interfaces/Messages"; \ No newline at end of file diff --git a/package.json b/package.json index 7e3daee..3c7ef70 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "nextjs-static-page-localizer", - "version": "1.0.17", + "version": "1.0.21", "description": "For creating localized pages in an application that needs to be compatible or able to run as a static web page", "main": "dist/index.js", "module": "dist/index.js", @@ -15,6 +15,12 @@ }, "keywords": [ "nextjs", + "react", + "next", + "i18n", + "localizer", + "internationalization", + "internationalisation", "azure", "localization", "static", @@ -37,35 +43,10 @@ "react-dom": "^18.2.0" }, "files": [ - "dist" - ], - "exports": { - ".": { - "import": "./dist/index.js", - "types": "./dist/index.d.ts" - }, - "./components": { - "import": "./dist/ui-components.js", - "types": "./dist/ui-components.d.ts" - }, - "./components/LanguageSwitcher": { - "import": "./dist/components/LanguageSwitcher.js", - "types": "./dist/components/LanguageSwitcher.d.ts" - }, - "./components/LocalizedLink": { - "import": "./dist/components/LocalizedLink.js", - "types": "./dist/components/LocalizedLink.d.ts" - }, - "./components/*": "./dist/components/*", - "./helpers": { - "import": "./dist/helpers/index.js", - "types": "./dist/helpers/index.d.ts" - }, - "./helpers/*": "./dist/helpers/*", - "./interfaces": { - "import": "./dist/interfaces/index.js", - "types": "./dist/interfaces/index.d.ts" - }, - "./interfaces/*": "./dist/interfaces/*" - } + "dist", + "components.js", + "components.d.ts", + "interfaces.js", + "interfaces.d.ts" + ] }