Documentation
Feedback
Guides
Learning Center

Learning Center
Learning Center
Práticas de internacionalização no VTEX IO
View in English
This content was migrated from the VTEX Learning Center and is no longer being actively maintained. For the most accurate and up-to-date information, please check the official documentation.

Introdução

Com o bloco customizado na loja, devemos aprender a internacionalizar o conteúdo apresentado.

É importante lembrar que os blocos devem sempre seguir boas práticas de localização, e não devem mostrar strings hardcoded, mas sim sensíveis a linguagem que a loja opera.

Não se preocupe, você não precisará adicionar traduções de todos os textos para as variadas linguagens nas quais o Store Framework é usado. Portanto, nessa etapa, serão apresentados conceitos acerca da internacionalização de apps e como fazê-la.

As Messages

O conceito de messages facilita a adição de novos idiomas ao tema. As messages centralizam todos os serviços de tradução na plataforma. Dado um texto a ser traduzido, Messages irá primeiramente checar o contexto definido pelo usuário para, em seguida, checar as traduções das apps e, por fim, passa pelo sistema de tradução automática.

Na estrutura do diretório, é possível observar que há uma pasta chamada messages, que apresenta três arquivos principais: pt.json, en.json e es.json, cada um responsável pelas traduções: português, inglês e espanhol, respectivamente. Além disso, a fim de fornecer traduções automáticas melhores, é utilizado o arquivo context.json, responsável por evitar ambiguidades.

Para utilizar tais definições, os arquivos de tradução mencionados anteriormente são JSON, cujas chaves são as mensagens e os valores são as traduções.

O arquivo context.json é necessário e precisa conter todas as mensagens, além de oferecer as traduções automáticas em casos excepcionais.

Internacionalizando seu bloco

Você já deve ter aprendido a usar o nosso builder messages, e será através dele que serão adicionadas strings internacionalizadas nos componentes.

  1. Para isso, na pasta /messages, adicione agora uma mensagem de título para o componente:

    messages/pt.json


    _10
    {
    _10
    ...,
    _10
    + "countdown.title": "Contagem Regressiva"
    _10
    }

    messages/en.json


    _10
    {
    _10
    ...,
    _10
    + "countdown.title": "Countdown"
    _10
    }

    messages/es.json


    _10
    {
    _10
    ...,
    _10
    + "countdown.title": "Cuenta Regresiva"
    _10
    }

    messages/context.json


    _10
    {
    _10
    ...,
    _10
    + "countdown.title": "Countdown"
    _10
    }

  2. Feito isso, para renderizar o título deve-se usar o componente FormattedMessage da biblioteca react-intl.

    A biblioteca react-intl dá suporte a várias maneiras de configuração e internacionalização, vale a pena verificá-las.

  3. Agora, adicione a biblioteca usando yarn add react-intl na pasta react. Feito isso, no código do seu componente Countdown.tsx,importe o FormattedMessage


    _10
    //react/Countdown.tsx
    _10
    + import { FormattedMessage } from 'react-intl'

  4. Também é necessário adicionar uma nova prop ao CountdownProps:


    _10
    interface CountdownProps {
    _10
    + title: string
    _10
    targetDate: string
    _10
    }

  5. Além disso, adicione uma constante que será o seu título:


    _10
    //react/Countdown.tsx
    _10
    const titleText = title || <FormattedMessage id="countdown.title" />

  6. Agora, junte o título e o contador para renderizá-los. Para isso, defina um container por fora. Além disso, o texto do título será passado através da prop title:


    _25
    //react/Countdown.tsx
    _25
    const Countdown: StorefrontFunctionComponent<CountdownProps> = ({
    _25
    title,
    _25
    targetDate,
    _25
    }) => {
    _25
    const [timeRemaining, setTime] = useState<TimeSplit>({
    _25
    hours: '00',
    _25
    minutes: '00',
    _25
    seconds: '00',
    _25
    })
    _25
    _25
    const titleText = title || <FormattedMessage id="countdown.title" />
    _25
    const handles = useCssHandles(CSS_HANDLES)
    _25
    _25
    tick(targetDate, setTime)
    _25
    _25
    return (
    _25
    <div className={`${handles.container} t-heading-2 fw3 w-100 c-muted-1`}>
    _25
    <div className={`${handles.title} db tc`}>{titleText}</div>
    _25
    <div className={`${handles.countdown} db tc`}>
    _25
    {`${timeRemaining.hours}:${timeRemaining.minutes}:${timeRemaining.seconds}`}
    _25
    </div>
    _25
    </div>
    _25
    )
    _25
    }

  7. Note que são utilizados três handles novos: container, countdown e title. Dessa forma, lembre-se de declará-los na constante CSS_HANDLES, vista na etapa anterior:


    _10
    //react/Countdown.tsx
    _10
    const CSS_HANDLES = ['container', 'countdown', 'title']

  8. Por fim, é preciso adicionar a prop de title no schema:


    _19
    //react/Countdown.tsx
    _19
    Countdown.schema = {
    _19
    title: 'editor.countdown.title',
    _19
    description: 'editor.countdown.description',
    _19
    type: 'object',
    _19
    properties: {
    _19
    + title: {
    _19
    + title: 'Sou um título',
    _19
    + type: 'string',
    _19
    + default: null,
    _19
    + },
    _19
    targetDate: {
    _19
    title: 'Data final',
    _19
    description: 'Data final usada no contador',
    _19
    type: 'string',
    _19
    default: null,
    _19
    },
    _19
    },
    _19
    }

Pronto! Agora, para testar sua loja em outros idiomas basta adicionar a query string /?cultureInfo=pt-br ou /?cultureInfo=es-ar na URL, por exemplo. Ao utilizar tal URL, o resultado esperado é esse aqui:

{"base64":"  ","img":{"width":3810,"height":1924,"type":"png","mime":"image/png","wUnits":"px","hUnits":"px","length":1134753,"url":"https://user-images.githubusercontent.com/19495917/75484759-23d7f000-5988-11ea-8b0a-63a5fce4ea7e.png"}}

Answer sheet

See answer sheet for Countdown.tsx
Countdown.tsx

_62
// store-block/react/Countdown.tsx
_62
import React, { useState } from 'react'
_62
import { TimeSplit } from './typings/global'
_62
import { tick, getTwoDaysFromNow } from './utils/time'
_62
import { useCssHandles } from 'vtex.css-handles'
_62
import { FormattedMessage } from 'react-intl'
_62
_62
interface CountdownProps {
_62
title: string
_62
targetDate: string
_62
}
_62
_62
const DEFAULT_TARGET_DATE = getTwoDaysFromNow()
_62
_62
const CSS_HANDLES = ['container', 'countdown', 'title']
_62
_62
const Countdown: StorefrontFunctionComponent<CountdownProps> = ({
_62
title,
_62
targetDate = DEFAULT_TARGET_DATE,
_62
}) => {
_62
const [timeRemaining, setTime] = useState<TimeSplit>({
_62
hours: '00',
_62
minutes: '00',
_62
seconds: '00',
_62
})
_62
_62
const titleText = title || <FormattedMessage id="countdown.title" />
_62
_62
const handles = useCssHandles(CSS_HANDLES)
_62
_62
tick(targetDate, setTime)
_62
_62
return (
_62
<div className={`${handles.container} t-heading-2 fw3 w-100 c-muted-1`}>
_62
<div className={`${handles.title} db tc`}>{titleText}</div>
_62
<div className={`${handles.countdown} db tc`}>
_62
{`${timeRemaining.hours}:${timeRemaining.minutes}:${timeRemaining.seconds}`}
_62
</div>
_62
</div>
_62
)
_62
}
_62
_62
Countdown.schema = {
_62
title: 'editor.countdown.title',
_62
description: 'editor.countdown.description',
_62
type: 'object',
_62
properties: {
_62
title: {
_62
title: 'I am a title',
_62
type: 'string',
_62
default: null,
_62
},
_62
targetDate: {
_62
title: 'Final date',
_62
description: 'Final date used in the countdown',
_62
type: 'string',
_62
default: null,
_62
},
_62
},
_62
}
_62
_62
export default Countdown

See answer sheet for context.json
context.json

_10
// store-block/messages/context.json
_10
{
_10
"editor.countdown.title": "Countdown",
_10
"editor.countdown.description": "Countdown component",
_10
"countdown.title": "Countdown"
_10
}

See answer sheet for en.json
en.json

_10
// store-block/messages/en.json
_10
{
_10
"editor.countdown.title": "Countdown",
_10
"editor.countdown.description": "Countdown component",
_10
"countdown.title": "Countdown"
_10
}

See answer sheet for es.json
es.json

_10
// store-block/messages/es.json
_10
{
_10
"editor.countdown.title": "Cuenta regresiva",
_10
"editor.countdown.description": "Cuenta regresiva component",
_10
"countdown.title": "Cuenta Regresiva"
_10
}

See answer sheet for pt.json
pt.json

_10
// store-block/messages/pt.json
_10
{
_10
"editor.countdown.title": "Contagem regressiva",
_10
"editor.countdown.description": "Componente de contagem regressiva",
_10
"countdown.title": "Contagem Regressiva"
_10
}

On this page