0

I'm using gatsby-plugin-react-i18next for translating my website, and it works with simple text. But when I try to format parts of the text, with bold text or italic text, it doesn't work (I don't know how to do it).

How can I format a specific part of a paragraph using i18n?

Below is an example of my setup.

page JS

const IndexPage = () => {

  const { t } = useTranslation();

  return (
    <Layout>
      <Seo title="Home" />
      <div>
          <h1>
            {t("HomepageHeader")} 
          </h1>
          <p>
            {t("HomepageDescription")} 
          </p>
      </div>
    </Layout>
  )
}

export default IndexPage

Folder structure:

locales

-en

--translation.json

-nl

--translation.json

Example JSON en

{
"HomepageHeader": "Grow your business with a modern website!",
"HomepageDescription": "Your website is the number 1 selling point, to your customers. Make sure you get the most out of it!"
}

How can I make for example only "number 1 selling point" in the HomepageDescription bold?

Bart
  • 149
  • 1
  • 16
  • I see that the answer has been asked and answered before: https://stackoverflow.com/a/67177072/15746655 – Bart Feb 14 '23 at 08:49

1 Answers1

0

Have a look at the Trans Component: https://react.i18next.com/latest/trans-component

Or use a markdown component, something like:

import React from 'react';
import Markdown from './Markdown';
import { useTranslation } from '../utils';

export function Text({
  i18nKey,
  ns = 'client-locize-app-loaders',
  i18nOptions = {},
  message,
  defaultValue,
  linkTarget = '_blank',
}) {
  const { t, ready } = useTranslation(ns, { useSuspense: false });
  if (!ready)
    return (
      <Markdown source={message || 'loading...'} noContainer options={{ linkTarget: '_blank' }} />
    );

  return (
    <Markdown
      source={message || t(i18nKey, { defaultValue, ...i18nOptions })}
      noContainer
      options={{ linkTarget }}
    />
  );
}

import React from 'react';
import { Remarkable } from 'remarkable';

export class Markdown extends React.Component {
  constructor(props) {
    super(props);

    this.content = this.content.bind(this);
    this.renderMarkdown = this.renderMarkdown.bind(this);
  }

  componentWillUpdate(nextProps, nextState) {
    if (nextProps.options !== this.props.options) {
      this.md = new Remarkable(nextProps.options);
    }
  }

  content() {
    if (this.props.source)
      return <span dangerouslySetInnerHTML={{ __html: this.renderMarkdown(this.props.source) }} />;

    return React.Children.map(this.props.children, (child) => {
      if (typeof child === 'string') {
        return <span dangerouslySetInnerHTML={{ __html: this.renderMarkdown(child) }} />;
      }
      return child;
    });
  }

  renderMarkdown(source) {
    if (!this.md) this.md = new Remarkable(this.props.options);
    if (this.props.renderInline) return this.md.renderInline(source);

    return this.md.render(source);
  }

  render() {
    const Container = this.props.container;

    if (this.props.noContainer) return this.content();

    return (
      <Container className={this.props.className} style={this.props.style}>
        {this.content()}
      </Container>
    );
  }
}

Markdown.defaultProps = {
  noContainer: false,
  renderInline: false,
  container: 'div',
  options: {},
  className: '',
};
adrai
  • 2,495
  • 1
  • 15
  • 18