Comments (15)
👍 for jsx support. I'd like to be able to do something like this:
var messages = {
"en": {
msgWithLinks: "In english {item1} link goes first then {item2}."
},
"es": {
msgWithLinks: "for some reason in this language, {item2} goes before {item1}"
}
};
var MyComponent = React.createClass({
mixins: [ReactIntlMixin],
render: function () {
return <p>{this.formatMessage(this.getIntlMessage("msgWithLinks"), {
item1: <a onClick={this._handle1}>Bob Smith</a>,
item2: <a onClick={this._handle2}>John D</a>,
})}</p>;
}
});
from formatjs.
This is a good question.
Generally, we'd recommend that you not mix HTML in with your translated string messages. Can you provide an example of a message with JSX code in it?
from formatjs.
@Jbelcher the problem with having markup within the messages is always escaping, but we haven't look at this problem from the react perspective, we will do.
from formatjs.
One example: Are you sure you want to delete <strong>{itemName}</strong>? This action <strong>CANNOT</strong> be undone.
The recommendation is reasonable, as this is an undesirable coupling with specific markup. There are workarounds as well (break the above into 5 messages, use dangerouslySetInnerHTML, wrap the plain message in some sort of imperative translation), but I am curious about any better approaches.
from formatjs.
@Jbelcher using dangerouslySetInnerHTML
would be the way I recommend handling this now.
I'm actively working on providing React components for each type of formatting so there's a declarative way via JSX to use this library (#24). Included will be a <Message>
component from which we might be able to do something more advanced for messages that contain HTML/JSX.
I'm currently unaware of a eval
-like public API provided by React so that the formatted string with JSX syntax can be processed by JSTransform. And if there is something, this wouldn't be a great option since it would requiring running the transform on every render in production.
The best option will probably be to create a <HTMLMessage>
component which would HTML-escape all its props before formatting the message, then use dangerouslySetInnerHTML
under the hood. We've actually done something similar in the handlebars-intl's {{formatHTMLMessage}} helper. Note that this would not support JSX though, just HTML.
from formatjs.
@ericf I like that approach, and the addition of an <HTMLMessage>
component (and really all of the declarative mixin components) sounds great. I don't see any problem in supporting only HTML either. Thanks for your thoughts (and formatjs/react-intl in general)!
from formatjs.
Re-opening this so that we can track it and auto-close it one a PR with a commit that fixes this lands in master
.
from formatjs.
👍
from formatjs.
@kyleboyle we are not likely to support this. In the PR linked above, we are HTML-escaping the values supplied to formatMessage()
, and only allow HTML to exist in the message itself using the upcoming <IntlHTMLMessage>
component.
We don't have any plans to make this package render sub React components when interpolating the translated message strings. But we will support adding HTML (not JSX) to these message strings. You're example could work like this:
var messages = {
"en": {
msgWithLinks: 'In english <a id="item1">{item1}</a> link goes first then <a id="item2">{item2}</a>.'
},
"es": {
msgWithLinks: 'for some reason in this language, <a id="item2">{item2}</a> goes before <a id="item1">{item1}</a>'
}
};
var MyComponent = React.createClass({
mixins: [ReactIntlMixin],
handleMessageClick: function (e) {
if (e.target.id === 'item1') {
// Handle item1 click.
return;
}
if (e.target.id === 'item2') {
// Handle item2 click.
return;
}
},
render: function () {
return (
<p onClick={this.handleMessageClick}>
<IntlHTMLMessage item1="Bob Smith" item2="John D">
{this.getIntlMessage("msgWithLinks")}
</IntlHTMLMessage>
</p>
);
}
});
from formatjs.
@ericf thanks very much for the response. I'm anxiously awaiting the next release.
from formatjs.
@kyleboyle the code is basically done for adding the components. We will do a v1.1.0-rc-1
release once we finish updating some of our tooling to make source maps better, and while people are testing the RC, we'll be working on updates to the docs. So it would be great if you would test things out in the RC once it's ready! I can ping you when it is.
from formatjs.
@ericf looking forward to this.Thanks!
from formatjs.
@ericf I'd be happy to try out the RC when it is ready. I'll keep my eye on the releases.
from formatjs.
I've been working on a way to allow React Elements to be passed as values when formatting messages, allowing for things like @kyleboyle's example above to work.
As for allowing JSX inside the ICU Message string itself, that won't be practical since it would require parsing it was JSX. So it seems we can support HTML inside the ICU Message string, or React Elements as placeholder values when formatting messages. I'm not yet sure if the union of these two things will be possible though (since HTML inside the messages requires dangerouslySetInnerHTML
).
See: #65 (comment)
from formatjs.
:bananadance:
from formatjs.
Related Issues (20)
- @formatjs/intl-numberformat/polyfill: roundingIncrement seems to be a no-op HOT 3
- [docs] Rich Text Formatting example doesn't work HOT 2
- Polyfill.io has been sold to a weird Chinese company and should no longer be recommended HOT 1
- chore: update tzdata to 2024a
- INVALID_TAG when parsing regular HTML tag with attribute HOT 1
- Can't catch error HOT 1
- Feature request: allow units greater than `day` in `FormattedRelativeTime` with `updateIntervalInSeconds` to be picked HOT 2
- It's incredibly slow on lower end Android devices HOT 2
- Intl.Segmenter: isWordLike does not match Node.js and browsers HOT 2
- @formatjs/intl-locale/polyfill-force TypeError: Error uninitialized locale at Locale2.getWeekInfo HOT 3
- .formatMessage is not working when provided messages has object with `type: 1` HOT 8
- Extract does not work on vue template since vue 3.4.0 HOT 1
- eslint-plugin-formatjs doesn't check `this.intl.formatMessage(...)` usages HOT 1
- `LocaleMatcher` doesn't work on propietary tags
- Node 20.12.1 x Jest; shouldPolyfill results in RangeError. Incorrect locale information provided
- eslint-plugin-formatjs and eslint v9 support
- Website - search is broken
- @formatjs/intl-localematcher documentation is wrong... incorrect order HOT 1
- @formatjs/swc-plugin-experimental incompatible with latest SWC core version HOT 1
- cli-lib's `extract` function ignores `throws` setting for errors in `processFile`
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from formatjs.