Skip to content
This repository has been archived by the owner on Jul 15, 2020. It is now read-only.

i18next support #85

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 50 additions & 10 deletions components/layout.js
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ export default class extends React.Component {
</div>
</div>
</Nav>
<UserMenu session={this.props.session} toggleModal={this.toggleModal} signinBtn={this.props.signinBtn}/>
<UserMenu session={this.props.session} toggleModal={this.toggleModal} signinBtn={this.props.signinBtn} i18n={this.props.i18n}/>
</div>
</Navbar>
<MainBody navmenu={this.props.navmenu} fluid={this.props.fluid} container={this.props.container}>
Expand Down Expand Up @@ -170,16 +170,26 @@ export class UserMenu extends React.Component {
this.handleSignoutSubmit = this.handleSignoutSubmit.bind(this)
}

async handleSignoutSubmit(event) {
event.preventDefault()

// Save current URL so user is redirected back here after signing out
const cookies = new Cookies()
cookies.set('redirect_url', window.location.pathname, { path: '/' })
async handleSignoutSubmit(event) {
event.preventDefault()

// Save current URL so user is redirected back here after signing out
const cookies = new Cookies()
cookies.set('redirect_url', window.location.pathname, { path: '/' })

await NextAuth.signout()
Router.push('/')
}

await NextAuth.signout()
Router.push('/')
}
changeLanguage = (e, lang) => {
e.preventDefault()
const { i18n } = this.props
i18n.reloadResources([lang])
i18n.changeLanguage(lang, (err, t) => {
if (err) console.error('something went wrong loading', err);
console.info('Language Changed:', `${t('hello')} ${lang}`)
})
}

render() {
if (this.props.session && this.props.session.user) {
Expand Down Expand Up @@ -221,6 +231,36 @@ export class UserMenu extends React.Component {
// If not signed in, display sign in button
return (
<Nav className="ml-auto" navbar>
<NavItem>
<div tabIndex="1" className="dropdown nojs-dropdown">
<div className="nav-item">
<span className="dropdown-toggle nav-link">Change Language</span>
</div>
<div className="dropdown-menu">
<a href="#" className="dropdown-item" onClick={(e) => this.changeLanguage(e, 'en_US')}>
<i className="flag flag-24 flag-us"></i>English - USA
</a>
<a href="#" className="dropdown-item" onClick={(e) => this.changeLanguage(e, 'en_GB')}>
<i className="flag flag-24 flag-gb"></i>English - GB
</a>
<a href="#" className="dropdown-item" onClick={(e) => this.changeLanguage(e, 'de')}>
<i className="flag flag-24 flag-de"></i>German
</a>
<a href="#" className="dropdown-item" onClick={(e) => this.changeLanguage(e, 'fr')}>
<i className="flag flag-24 flag-fr"></i>French
</a>
<a href="#" className="dropdown-item" onClick={(e) => this.changeLanguage(e, 'it')}>
<i className="flag flag-24 flag-it"></i>Italian
</a>
<a href="#" className="dropdown-item" onClick={(e) => this.changeLanguage(e, 'es')}>
<i className="flag flag-24 flag-es"></i>Spanish
</a>
<a href="#" className="dropdown-item" onClick={(e) => this.changeLanguage(e, 'tr')}>
<i className="flag flag-24 flag-tr"></i>Turkish
</a>
</div>
</div>
</NavItem>
<NavItem>
{/**
* @TODO Add support for passing current URL path as redirect URL
Expand Down
2 changes: 1 addition & 1 deletion components/page.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export default class extends React.Component {
static async getInitialProps({req}) {
return {
session: await NextAuth.init({req}),// Add this.props.session to all pages
lang: 'en'// Add a lang property for accessibility
lang: req ? req.locale : 'en'// Getting browser lang from req or setting a default
}
}

Expand Down
26 changes: 26 additions & 0 deletions css/flag-sprites.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
Took necessary parts from https://github.com/flarik/css-sprite-flags
*/

.flag {
display: inline-block;
background-repeat: no-repeat;
}

.flag.flag-24 {
display: inline-block;
width: 24px;
height: 24px;
background-image: url('/static/sprite-flags-24x24.png');
background-repeat: no-repeat;
vertical-align: middle;
margin-right: 6px;
}

.flag.flag-24.flag-de { background-position: -144px -96px; }
.flag.flag-24.flag-es { background-position: -0px -120px; }
.flag.flag-24.flag-fr { background-position: -192px -120px; }
.flag.flag-24.flag-gb { background-position: -240px -120px; }
.flag.flag-24.flag-it { background-position: -144px -168px; }
.flag.flag-24.flag-us { background-position: -168px -336px; }
.flag.flag-24.flag-tr { background-position: -0px -336px; }
1 change: 1 addition & 0 deletions css/index.scss
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ $ionicons-version: "3.0.0-alpha.3" !default;
@import "../node_modules/bootstrap/scss/bootstrap.scss";
@import "../node_modules/react-bootstrap-table/dist/react-bootstrap-table-all.min";
@import "nojs-menus.scss";
@import "flag-sprites.scss";

.lead {
font-size: 1.4em;
Expand Down
63 changes: 63 additions & 0 deletions helpers/i18next.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import i18n from 'i18next'
import XHR from 'i18next-xhr-backend';
import fetch from 'isomorphic-fetch'
/**
* Initialize a i18next instance.
* @function startI18n
* @param {object} session - Session params.
* @param {string} lang - Active language.
* @param {object} i18nOptions - Custom options for i18n
*/
const startI18n = (session, lang, i18nOptions) => {
const defaults = {
lng: lang, // active language http://i18next.com/translate/
fallbackLng: 'en',
ns: ['common'],
defaultNS: 'common',
debug: false,
backend: {
// path where resources get loaded from, or a function
// returning a path:
// function(lngs, namespaces) { return customPath; }
// the returned path will interpolate lng, ns if provided like giving a static path
loadPath: '/translations/{{lng}}/{{ns}}.json',

// your backend server supports multiloading
// /locales/resources.json?lng=de+en&ns=ns1+ns2
allowMultiLoading: false, // set loadPath: '/locales/resources.json?lng={{lng}}&ns={{ns}}' to adapt to multiLoading

// allow cross domain requests
crossDomain: true,

// allow credentials on cross domain requests
withCredentials: true,

// define a custom xhr function
// can be used to support XDomainRequest in IE 8 and 9
ajax: (url, options, callback, data) => {
const fetchOptions = {
method: 'GET',
headers: {
'X-CSRF-TOKEN': session.csrfToken,
'content-type': 'application/json'
}
}
if (data) {
fetchOptions.method = 'POST',
fetchOptions.body = data
}
// TODO: dynamic domain
fetch(`http://localhost:3000${url}`, fetchOptions)
.then(response => response.json())
.then(responseJson => {
callback(JSON.stringify(responseJson), { status: 200 })
})
.catch((error) => console.error('i18n fetch error:', error))
}
}
}

return i18n.use(XHR).init((i18nOptions ? Object.assign({}, defaults, i18nOptions) : defaults))
}

export { startI18n }
10 changes: 10 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
'use strict'

const locale = require('locale')
const next = require('next')
const nextAuth = require('next-auth')
const nextAuthConfig = require('./next-auth.config')
Expand All @@ -9,6 +10,9 @@ const routes = {
account: require('./routes/account')
}

const supportedLocales = ['en_US', 'en_GB', 'en', 'de', 'es', 'fr', 'it', 'tr']
const defaultLocale = 'en'

// Load environment variables from .env file if present
require('dotenv').load()

Expand Down Expand Up @@ -50,6 +54,12 @@ nextApp
const express = nextAuthOptions.express
const expressApp = nextAuthOptions.expressApp

// Set locale middleware for browser locale detection
expressApp.use(locale(supportedLocales, defaultLocale))

// Serve translations
expressApp.use('/translations', express.static('./translations'))

// Add admin routes
routes.admin(expressApp)

Expand Down
Loading