Skip to content

Commit 27645b7

Browse files
committed
feat: add multilingual support
1 parent 946520a commit 27645b7

File tree

13 files changed

+187
-70
lines changed

13 files changed

+187
-70
lines changed

README.md

+7
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,9 @@ netlifyIdentity.logout();
7474
// refresh the user's JWT
7575
// Note: this method returns a promise.
7676
netlifyIdentity.refresh().then((jwt)=>console.log(jwt))
77+
78+
// Change language
79+
netlifyIdentity.setLocale('en');
7780
```
7881

7982
#### A note on script tag versioning
@@ -120,6 +123,9 @@ netlifyIdentity.logout();
120123
// Note: this method returns a promise.
121124
netlifyIdentity.refresh().then((jwt)=>console.log(jwt))
122125

126+
// Change language
127+
netlifyIdentity.setLocale('en');
128+
123129
// Access the underlying GoTrue JS client.
124130
// Note that doing things directly through the GoTrue client brings a risk of getting out of
125131
// sync between your state and the widget’s state.
@@ -136,6 +142,7 @@ module API. Options include:
136142
container: '#some-query-selector'; // container to attach to
137143
APIUrl: 'https://www.example.com/.netlify/functions/identity'; // Absolute url to endpoint. ONLY USE IN SPECIAL CASES!
138144
namePlaceholder: 'some-placeholder-for-Name'; // custom placeholder for name input form
145+
locale: 'en'; // language code for translations - available: en, fr - default to en
139146
}
140147
```
141148

src/components/app.js

+24-19
Original file line numberDiff line numberDiff line change
@@ -11,48 +11,48 @@ const pagesWithHeader = { login: true, signup: true };
1111
const pages = {
1212
login: {
1313
login: true,
14-
button: "Log in",
15-
button_saving: "Logging in",
14+
button: "log_in",
15+
button_saving: "logging_in",
1616
email: true,
1717
password: true,
1818
link: "amnesia",
19-
link_text: "Forgot password?",
19+
link_text: "forgot_password",
2020
providers: true
2121
},
2222
signup: {
2323
signup: true,
24-
button: "Sign up",
25-
button_saving: "Signing Up",
24+
button: "sign_up",
25+
button_saving: "signing_up",
2626
name: true,
2727
email: true,
2828
password: true,
2929
providers: true
3030
},
3131
amnesia: {
32-
title: "Recover password",
33-
button: "Send recovery email",
34-
button_saving: "Sending recovery email",
32+
title: "recover_password",
33+
button: "send_recovery_email",
34+
button_saving: "sending_recovery_email",
3535
email: true,
3636
link: "login",
37-
link_text: "Never mind"
37+
link_text: "never_mind"
3838
},
3939
recovery: {
40-
title: "Recover password",
41-
button: "Update password",
42-
button_saving: "Updating password",
40+
title: "recover_password",
41+
button: "update_password",
42+
button_saving: "updating_password",
4343
password: true,
4444
link: "login",
45-
link_text: "Never mind"
45+
link_text: "never_mind"
4646
},
4747
invite: {
48-
title: "Complete your signup",
49-
button: "Sign up",
50-
button_saving: "Signing Up",
48+
title: "complete_your_signup",
49+
button: "sign_up",
50+
button_saving: "signing_up",
5151
password: true,
5252
providers: true
5353
},
5454
user: {
55-
title: "Logged in"
55+
title: "logged_in"
5656
}
5757
};
5858

@@ -96,6 +96,7 @@ class App extends Component {
9696
<SiteURLForm
9797
devMode={store.siteURL != null}
9898
onSiteURL={store.siteURL ? this.clearSiteURL : this.handleSiteURL}
99+
t={store.translate}
99100
/>
100101
);
101102
}
@@ -108,11 +109,12 @@ class App extends Component {
108109
user={store.user}
109110
saving={store.saving}
110111
onLogout={this.handleLogout}
112+
t={store.translate}
111113
/>
112114
);
113115
}
114116
if (store.modal.page === "signup" && store.settings.disable_signup) {
115-
return <Message type="signup_disabled" />;
117+
return <Message type="signup_disabled" t={store.translate} />;
116118
}
117119

118120
return (
@@ -123,19 +125,21 @@ class App extends Component {
123125
saving={store.saving}
124126
onSubmit={this.handleUser}
125127
namePlaceholder={store.namePlaceholder}
128+
t={store.translate}
126129
/>
127130
{!store.user && page.link && store.gotrue && (
128131
<button
129132
onclick={pageLinkHandler}
130133
className="btnLink forgotPasswordLink"
131134
>
132-
{page.link_text}
135+
{store.translate(page.link_text)}
133136
</button>
134137
)}
135138
{store.isLocal ? (
136139
<SiteURLForm
137140
devMode={store.siteURL != null}
138141
onSiteURL={store.siteURL ? this.clearSiteURL : this.handleSiteURL}
142+
t={store.translate}
139143
/>
140144
) : (
141145
<div />
@@ -195,6 +199,7 @@ class App extends Component {
195199
onPage={this.handlePage}
196200
onClose={this.handleClose}
197201
logo={store.modal.logo}
202+
t={store.translate}
198203
>
199204
{this.renderBody()}
200205
{this.renderProviders()}

src/components/controls.js

+6-6
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ class Controls extends Component {
2424
};
2525

2626
render() {
27-
const { user } = this.props.store;
27+
const { user, translate: t } = this.props.store;
2828

2929
if (this.props.mode === "button") {
3030
return (
@@ -33,7 +33,7 @@ class Controls extends Component {
3333
href="#"
3434
onClick={this.handleButton}
3535
>
36-
{this.props.text || (user ? "Log out" : "Log in")}
36+
{this.props.text || (user ? t("log_out") : t("log_in"))}
3737
</a>
3838
);
3939
}
@@ -42,7 +42,7 @@ class Controls extends Component {
4242
return (
4343
<ul className="netlify-identity-menu">
4444
<li className="netlify-identity-item netlify-identity-user-details">
45-
Logged in as{" "}
45+
{t("logged_in_as")}{" "}
4646
<span className="netlify-identity-user">
4747
{user.user_metadata.name || user.email}
4848
</span>
@@ -53,7 +53,7 @@ class Controls extends Component {
5353
href="#"
5454
onClick={this.handleLogout}
5555
>
56-
Log out
56+
{t("log_out")}
5757
</a>
5858
</li>
5959
</ul>
@@ -68,7 +68,7 @@ class Controls extends Component {
6868
href="#"
6969
onClick={this.handleSignup}
7070
>
71-
Sign up
71+
{t("sign_up")}
7272
</a>
7373
</li>
7474
<li className="netlify-identity-item">
@@ -77,7 +77,7 @@ class Controls extends Component {
7777
href="#"
7878
onClick={this.handleLogin}
7979
>
80-
Log in
80+
{t("log_in")}
8181
</a>
8282
</li>
8383
</ul>

src/components/forms/logout.js

+7-3
Original file line numberDiff line numberDiff line change
@@ -7,22 +7,26 @@ export default class LogoutForm extends Component {
77
this.props.onLogout();
88
};
99
render() {
10-
const { user, saving } = this.props;
10+
const { user, saving, t } = this.props;
1111

1212
return (
1313
<form
1414
onSubmit={this.handleLogout}
1515
className={`form ${saving ? "disabled" : ""}`}
1616
>
1717
<p className="infoText">
18-
Logged in as <br />
18+
{t("logged_in_as")} <br />
1919
<span className="infoTextEmail">
2020
{user.user_metadata.full_name ||
2121
user.user_metadata.name ||
2222
user.email}
2323
</span>
2424
</p>
25-
<Button saving={saving} text="Log out" saving_text="Logging out" />
25+
<Button
26+
saving={saving}
27+
text={t("log_out")}
28+
saving_text={t("logging_out")}
29+
/>
2630
</form>
2731
);
2832
}

src/components/forms/message.js

+7-11
Original file line numberDiff line numberDiff line change
@@ -3,38 +3,34 @@ import { h, Component } from "preact";
33
const messages = {
44
confirm: {
55
type: "success",
6-
text:
7-
"A confirmation message was sent to your email, click the link there to continue."
6+
text: "message_confirm"
87
},
98
password_mail: {
109
type: "success",
11-
text:
12-
"We've sent a recovery email to your account, follow the link there to reset your password."
10+
text: "message_password_mail"
1311
},
1412
email_changed: {
1513
type: "sucess",
16-
text: "Your email address has been updated!"
14+
text: "message_email_changed"
1715
},
1816
verfication_error: {
1917
type: "error",
20-
text:
21-
"There was an error verifying your account. Please try again or contact an administrator."
18+
text: "message_verfication_error"
2219
},
2320
signup_disabled: {
2421
type: "error",
25-
text:
26-
"Public signups are disabled. Contact an administrator and ask for an invite."
22+
text: "message_signup_disabled"
2723
}
2824
};
2925

3026
export default class Message extends Component {
3127
render() {
32-
const { type } = this.props;
28+
const { type, t } = this.props;
3329
const msg = messages[type];
3430

3531
return (
3632
<div className={`flashMessage ${msg.type}`}>
37-
<span>{msg.text}</span>
33+
<span>{t(msg.text)}</span>
3834
</div>
3935
);
4036
}

src/components/forms/siteurl.js

+7-12
Original file line numberDiff line numberDiff line change
@@ -22,37 +22,32 @@ export default class SiteURLForm extends Component {
2222

2323
render() {
2424
const { url, development } = this.state;
25+
const { t } = this.props;
2526

2627
return (
2728
<div>
2829
{development ? (
2930
<div class="subheader">
30-
<h3>Development Settings</h3>
31+
<h3>{t("site_url_title")}</h3>
3132
<button
3233
onclick={e => this.clearSiteURL(e)}
3334
className="btnLink forgotPasswordLink"
3435
>
35-
Clear localhost URL
36+
{t("site_url_link_text")}
3637
</button>
3738
</div>
3839
) : (
3940
<form onsubmit={this.addSiteURL} className="form">
40-
<div className="flashMessage">
41-
{
42-
"Looks like you're running a local server. Please let us know the URL of your Netlify site."
43-
}
44-
</div>
41+
<div className="flashMessage">{t("site_url_message")}</div>
4542
<div className="formGroup">
4643
<label>
47-
<span className="visuallyHidden">
48-
Enter your Netlify Site URL
49-
</span>
44+
<span className="visuallyHidden">{t("site_url_label")}</span>
5045
<input
5146
className="formControl"
5247
type="url"
5348
name="url"
5449
value={url}
55-
placeholder="URL of your Netlify site"
50+
placeholder={t("site_url_placeholder")}
5651
autocapitalize="off"
5752
required
5853
oninput={this.handleInput}
@@ -61,7 +56,7 @@ export default class SiteURLForm extends Component {
6156
</label>
6257
</div>
6358
<button type="submit" className="btn">
64-
Set site's URL
59+
{t("site_url_submit")}
6560
</button>
6661
</form>
6762
)}

0 commit comments

Comments
 (0)