@intlayer/docs 9.3.1 → 9.3.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/blog/ar/nextjs-multilingual-seo-comparison.md +10 -10
- package/blog/de/nextjs-multilingual-seo-comparison.md +9 -9
- package/blog/en/nextjs-multilingual-seo-comparison.md +10 -10
- package/blog/en-GB/nextjs-multilingual-seo-comparison.md +10 -10
- package/blog/es/nextjs-multilingual-seo-comparison.md +10 -10
- package/blog/fr/nextjs-multilingual-seo-comparison.md +10 -10
- package/blog/hi/nextjs-multilingual-seo-comparison.md +10 -10
- package/blog/id/nextjs-multilingual-seo-comparison.md +10 -10
- package/blog/it/nextjs-multilingual-seo-comparison.md +10 -10
- package/blog/ja/nextjs-multilingual-seo-comparison.md +9 -9
- package/blog/ko/nextjs-multilingual-seo-comparison.md +9 -9
- package/blog/pl/nextjs-multilingual-seo-comparison.md +10 -10
- package/blog/pt/nextjs-multilingual-seo-comparison.md +9 -9
- package/blog/ru/nextjs-multilingual-seo-comparison.md +9 -9
- package/blog/tr/nextjs-multilingual-seo-comparison.md +9 -9
- package/blog/uk/nextjs-multilingual-seo-comparison.md +10 -10
- package/blog/vi/nextjs-multilingual-seo-comparison.md +10 -10
- package/blog/zh/nextjs-multilingual-seo-comparison.md +10 -10
- package/dist/cjs/generated/docs.entry.cjs +20 -0
- package/dist/cjs/generated/docs.entry.cjs.map +1 -1
- package/dist/esm/generated/docs.entry.mjs +20 -0
- package/dist/esm/generated/docs.entry.mjs.map +1 -1
- package/dist/types/generated/docs.entry.d.ts +1 -0
- package/dist/types/generated/docs.entry.d.ts.map +1 -1
- package/docs/ar/bundle_optimization.md +1 -1
- package/docs/ar/configuration.md +32 -9
- package/docs/ar/dictionary/content_file.md +0 -22
- package/docs/ar/dictionary/function_fetching.md +23 -0
- package/docs/ar/eslint.md +336 -0
- package/docs/ar/intlayer_with_react_router_v7_fs_routes.md +1 -1
- package/docs/bn/configuration.md +34 -9
- package/docs/bn/eslint.md +336 -0
- package/docs/cs/bundle_optimization.md +1 -1
- package/docs/cs/configuration.md +33 -9
- package/docs/cs/eslint.md +336 -0
- package/docs/de/bundle_optimization.md +1 -1
- package/docs/de/configuration.md +34 -9
- package/docs/de/dictionary/content_file.md +0 -22
- package/docs/de/dictionary/function_fetching.md +23 -0
- package/docs/de/eslint.md +336 -0
- package/docs/en/bundle_optimization.md +1 -1
- package/docs/en/configuration.md +34 -9
- package/docs/en/dictionary/content_file.md +0 -22
- package/docs/en/dictionary/function_fetching.md +23 -0
- package/docs/en/eslint.md +336 -0
- package/docs/en/packages/intlayer/getLocalizedPath.md +70 -19
- package/docs/en-GB/configuration.md +33 -9
- package/docs/en-GB/dictionary/content_file.md +0 -22
- package/docs/en-GB/dictionary/function_fetching.md +23 -0
- package/docs/en-GB/eslint.md +336 -0
- package/docs/en-GB/intlayer_with_create_react_app.md +32 -35
- package/docs/en-GB/intlayer_with_react_router_v7_fs_routes.md +1 -1
- package/docs/es/bundle_optimization.md +1 -1
- package/docs/es/configuration.md +35 -9
- package/docs/es/dictionary/content_file.md +0 -22
- package/docs/es/dictionary/function_fetching.md +23 -0
- package/docs/es/eslint.md +336 -0
- package/docs/fr/bundle_optimization.md +1 -1
- package/docs/fr/configuration.md +35 -9
- package/docs/fr/dictionary/content_file.md +0 -22
- package/docs/fr/dictionary/function_fetching.md +23 -0
- package/docs/fr/eslint.md +336 -0
- package/docs/hi/configuration.md +35 -9
- package/docs/hi/dictionary/content_file.md +0 -22
- package/docs/hi/dictionary/function_fetching.md +23 -0
- package/docs/hi/eslint.md +336 -0
- package/docs/hi/intlayer_with_react_router_v7_fs_routes.md +1 -1
- package/docs/hi/intlayer_with_vite+svelte.md +2 -2
- package/docs/id/configuration.md +35 -9
- package/docs/id/dictionary/content_file.md +0 -22
- package/docs/id/dictionary/function_fetching.md +23 -0
- package/docs/id/eslint.md +336 -0
- package/docs/it/bundle_optimization.md +1 -1
- package/docs/it/configuration.md +35 -9
- package/docs/it/dictionary/content_file.md +0 -22
- package/docs/it/dictionary/function_fetching.md +23 -0
- package/docs/it/eslint.md +336 -0
- package/docs/ja/configuration.md +30 -9
- package/docs/ja/dictionary/content_file.md +0 -22
- package/docs/ja/dictionary/function_fetching.md +23 -0
- package/docs/ja/eslint.md +336 -0
- package/docs/ja/intlayer_with_react_router_v7.md +1 -146
- package/docs/ja/intlayer_with_vite+react.md +5 -1
- package/docs/ko/configuration.md +31 -9
- package/docs/ko/dictionary/content_file.md +0 -22
- package/docs/ko/dictionary/function_fetching.md +23 -0
- package/docs/ko/eslint.md +336 -0
- package/docs/ko/intlayer_with_lynx+react.md +4 -0
- package/docs/ko/intlayer_with_react_router_v7_fs_routes.md +1 -1
- package/docs/ko/intlayer_with_storybook.md +5 -5
- package/docs/nl/configuration.md +33 -9
- package/docs/nl/eslint.md +336 -0
- package/docs/pl/bundle_optimization.md +1 -1
- package/docs/pl/configuration.md +34 -9
- package/docs/pl/dictionary/content_file.md +0 -22
- package/docs/pl/dictionary/function_fetching.md +23 -0
- package/docs/pl/eslint.md +336 -0
- package/docs/pl/intlayer_with_astro.md +1 -114
- package/docs/pl/migration_from_i18next_to_intlayer.md +4 -0
- package/docs/pl/migration_from_next-i18next_to_intlayer.md +8 -4
- package/docs/pl/migration_from_next-intl_to_intlayer.md +11 -5
- package/docs/pl/migration_from_nuxtjs_i18n_to_intlayer.md +8 -4
- package/docs/pl/migration_from_react-i18next_to_intlayer.md +8 -4
- package/docs/pl/migration_from_vue-i18n_to_intlayer.md +4 -0
- package/docs/pt/bundle_optimization.md +1 -1
- package/docs/pt/configuration.md +34 -9
- package/docs/pt/dictionary/content_file.md +0 -22
- package/docs/pt/dictionary/function_fetching.md +23 -0
- package/docs/pt/eslint.md +336 -0
- package/docs/pt/intlayer_with_astro.md +1 -114
- package/docs/ru/bundle_optimization.md +1 -1
- package/docs/ru/configuration.md +34 -9
- package/docs/ru/dictionary/content_file.md +0 -22
- package/docs/ru/dictionary/function_fetching.md +23 -0
- package/docs/ru/eslint.md +336 -0
- package/docs/tr/bundle_optimization.md +1 -1
- package/docs/tr/configuration.md +33 -9
- package/docs/tr/dictionary/content_file.md +0 -22
- package/docs/tr/dictionary/function_fetching.md +23 -0
- package/docs/tr/eslint.md +336 -0
- package/docs/uk/configuration.md +35 -9
- package/docs/uk/dictionary/content_file.md +0 -22
- package/docs/uk/dictionary/function_fetching.md +23 -0
- package/docs/uk/eslint.md +336 -0
- package/docs/uk/packages/angular-intlayer/exports.md +2 -2
- package/docs/ur/configuration.md +35 -9
- package/docs/ur/eslint.md +336 -0
- package/docs/vi/bundle_optimization.md +1 -1
- package/docs/vi/configuration.md +33 -9
- package/docs/vi/dictionary/content_file.md +0 -22
- package/docs/vi/dictionary/function_fetching.md +23 -0
- package/docs/vi/eslint.md +336 -0
- package/docs/zh/bundle_optimization.md +1 -1
- package/docs/zh/configuration.md +29 -9
- package/docs/zh/dictionary/content_file.md +0 -22
- package/docs/zh/dictionary/function_fetching.md +23 -0
- package/docs/zh/eslint.md +336 -0
- package/docs/zh/intlayer_with_create_react_app.md +4 -0
- package/docs/zh/intlayer_with_lynx+react.md +4 -0
- package/docs/zh/intlayer_with_nextjs_14.md +0 -2
- package/docs/zh/intlayer_with_nextjs_15.md +0 -2
- package/docs/zh/intlayer_with_nextjs_page_router.md +0 -2
- package/docs/zh/intlayer_with_nuxt.md +1 -1
- package/docs/zh/intlayer_with_react_router_v7.md +4 -0
- package/docs/zh/intlayer_with_react_router_v7_fs_routes.md +4 -0
- package/docs/zh/intlayer_with_solid_start.md +1 -1
- package/docs/zh/intlayer_with_vite+vue.md +0 -2
- package/docs/zh-TW/bundle_optimization.md +1 -1
- package/docs/zh-TW/eslint.md +336 -0
- package/package.json +7 -7
- package/src/generated/docs.entry.ts +20 -0
package/docs/pt/configuration.md
CHANGED
|
@@ -478,6 +478,29 @@ const config: IntlayerConfig = {
|
|
|
478
478
|
*/
|
|
479
479
|
purge: true,
|
|
480
480
|
|
|
481
|
+
/**
|
|
482
|
+
* Agrupar os chunks de dicionário por idioma de acordo com o limite de
|
|
483
|
+
* code-splitting que os utiliza, para que uma página carregada de forma
|
|
484
|
+
* preguiçosa obtenha seu conteúdo em uma única requisição.
|
|
485
|
+
* Padrão: true
|
|
486
|
+
*
|
|
487
|
+
* Nota:
|
|
488
|
+
* - Aplica-se apenas a dicionários que usam `importMode: 'dynamic'`.
|
|
489
|
+
*/
|
|
490
|
+
chunkGrouping: true,
|
|
491
|
+
|
|
492
|
+
/**
|
|
493
|
+
* Carregar um dicionário junto com o chunk que o utiliza, em vez de buscá-lo
|
|
494
|
+
* depois que esse chunk renderiza. Os leitores renderizam de forma síncrona em
|
|
495
|
+
* vez de suspender, então navegar não exibe mais um piscar de carregamento.
|
|
496
|
+
* Padrão: true
|
|
497
|
+
*
|
|
498
|
+
* Nota:
|
|
499
|
+
* - Apenas o idioma resolvido é aguardado, portanto a página baixa somente o
|
|
500
|
+
* idioma que exibe.
|
|
501
|
+
*/
|
|
502
|
+
dictionariesPreload: true,
|
|
503
|
+
|
|
481
504
|
/**
|
|
482
505
|
* Formato de saída para os ficheiros de dicionário gerados.
|
|
483
506
|
* Padrão: ['cjs', 'esm']
|
|
@@ -1057,15 +1080,17 @@ As opções de build aplicam-se aos plugins `@intlayer/babel` e `@intlayer/swc`.
|
|
|
1057
1080
|
|
|
1058
1081
|
> Durante a otimização, o Intlayer substituirá as chamadas aos dicionários para otimizar o chunking, de forma a que o bundle final importe apenas os dicionários efetivamente utilizados.
|
|
1059
1082
|
|
|
1060
|
-
| Campo
|
|
1061
|
-
|
|
|
1062
|
-
| `mode`
|
|
1063
|
-
| `optimize`
|
|
1064
|
-
| `minify`
|
|
1065
|
-
| `purge`
|
|
1066
|
-
| `checkTypes`
|
|
1067
|
-
| `
|
|
1068
|
-
| `
|
|
1083
|
+
| Campo | Descrição | Tipo | Padrão | Exemplo | Nota |
|
|
1084
|
+
| --------------------- | ---------------------------------------------------------------------------------------------------------------------------------- | -------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
1085
|
+
| `mode` | Controla o modo de build. | `'auto'` | <br/> `'manual'` | `'auto'` | `'manual'` | • `'auto'`: build acionada automaticamente durante a build da app.<br/>• `'manual'`: executada apenas quando o comando de build é explicitamente chamado.<br/>• Pode ser usado para desativar builds de dicionários (ex: para evitar a execução em ambientes Node.js). |
|
|
1086
|
+
| `optimize` | Controla se a build deve ser otimizada. | `boolean` | `undefined` | `process.env.NODE_ENV === 'production'` | • Se não definido, a otimização é acionada na build da framework (Vite/Next.js).<br/>• `true` força a otimização mesmo no modo dev.<br/>• `false` desativa-a.<br/>• Se ativo, substitui chamadas a dicionários para otimizar o chunking.<br/>• Requer plugins `@intlayer/babel` e `@intlayer/swc`. |
|
|
1087
|
+
| `minify` | Minifica os dicionários para reduzir o tamanho do bundle. | `boolean` | `false` | | • Indica se o bundle deve ser minificado.<br/>• Padrão: `true` em produção.<br/>• Esta opção será ignorada se `optimize` estiver desativada.<br/>• Esta opção será ignorada se `editor.enabled` for true. |
|
|
1088
|
+
| `purge` | Purga as chaves não utilizadas nos dicionários. | `boolean` | `false` | | • Indica se o bundle deve ser limpo.<br/>• Padrão: `true` em produção.<br/>• Esta opção será ignorada se `optimize` estiver desativada. |
|
|
1089
|
+
| `checkTypes` | Indica se a build deve verificar os tipos TypeScript e registar erros. | `boolean` | `false` | | Pode tornar o processo de build mais lento. |
|
|
1090
|
+
| `chunkGrouping` | Indica se os chunks de dicionário por idioma devem ser agrupados de acordo com o limite de code-splitting que os utiliza. | `boolean` | `true` | | • Sem agrupamento, uma página composta por muitos componentes emite uma requisição por dicionário.<br/>• Dicionários alcançados a partir de vários limites vão para um chunk compartilhado, então nenhuma página entrega o conteúdo de outra.<br/>• Aplica-se apenas a dicionários que usam `importMode: 'dynamic'`.<br/>• Aplica-se apenas à build do cliente, e somente ao empacotar (não em desenvolvimento). |
|
|
1091
|
+
| `dictionariesPreload` | Indica se um dicionário deve ser carregado junto com o chunk que o utiliza, em vez de ser buscado depois que esse chunk renderiza. | `boolean` | `true` | | • O ponto de entrada gerado aguarda o idioma de navegação no nível superior, então uma rota carregada de forma preguiçosa não é considerada carregada até que seu conteúdo esteja disponível.<br/>• Os leitores renderizam de forma síncrona em vez de suspender, então navegar não exibe mais um piscar de carregamento.<br/>• Apenas o idioma resolvido é aguardado, portanto a página baixa somente o idioma que exibe.<br/>• Aplica-se apenas a dicionários que usam `importMode: 'dynamic'`, na build do cliente.<br/>• Requer um empacotador com suporte a top-level await (Vite, esbuild). |
|
|
1092
|
+
| `outputFormat` | Controla o formato de saída dos dicionários. | `('esm' | 'cjs')[]` | `['esm', 'cjs']` | `['cjs']` | |
|
|
1093
|
+
| `traversePattern` | Padrões que definem quais ficheiros percorrer durante a otimização. | `string[]` | `['**/*.{tsx,ts,js,mjs,cjs,jsx,vue,svelte,svte}', '!**/node_modules/**', '!**/dist/**', '!**/.intlayer/**', '!**/*.config.*', '!**/*.test.*', '!**/*.spec.*', '!**/*.stories.*']` | `['src/**/*.{ts,tsx}', '../ui-library/**/*.{ts,tsx}', '!**/node_modules/**']` | • Limite a otimização a ficheiros relevantes para melhorar o desempenho da build.<br/>• Ignorado se `optimize` estiver desativado.<br/>• Utiliza padrões glob. |
|
|
1069
1094
|
|
|
1070
1095
|
---
|
|
1071
1096
|
|
|
@@ -533,28 +533,6 @@ Usado em conjunto com as Variantes, este campo define alternativas de conteúdo
|
|
|
533
533
|
|
|
534
534
|
> Veja [Variantes](https://github.com/aymericzip/intlayer/blob/main/docs/docs/pt/dynamic_dictionaries/variants.md) para mais informações.
|
|
535
535
|
|
|
536
|
-
#### `meta` (`Record<string, string | number | boolean>`)
|
|
537
|
-
|
|
538
|
-
Usado em conjunto com os Registros Dinâmicos, este campo permite declarar registros gerenciados pelo CMS ou dados arbitrários buscados em tempo de execução por um ID opaco. A identidade do dicionário é definida pelo conjunto arbitrário de pares chave-valor declarados neste campo `meta`.
|
|
539
|
-
|
|
540
|
-
**Exemplo:**
|
|
541
|
-
|
|
542
|
-
```typescript
|
|
543
|
-
{
|
|
544
|
-
key: "product-copy",
|
|
545
|
-
meta: {
|
|
546
|
-
id: "prod_abc",
|
|
547
|
-
userId: "user_123"
|
|
548
|
-
},
|
|
549
|
-
content: {
|
|
550
|
-
name: "Widget Pro",
|
|
551
|
-
description: "The best widget."
|
|
552
|
-
}
|
|
553
|
-
}
|
|
554
|
-
```
|
|
555
|
-
|
|
556
|
-
> Veja [Registros Dinâmicos](https://github.com/aymericzip/intlayer/blob/main/docs/docs/pt/dynamic_dictionaries/dynamic_content.md) para mais informações.
|
|
557
|
-
|
|
558
536
|
### Propriedades do CMS
|
|
559
537
|
|
|
560
538
|
##### `version` (string)
|
|
@@ -89,6 +89,29 @@ Não é possível buscar conteúdo de um arquivo JSON, use um arquivo .ts ou .js
|
|
|
89
89
|
|
|
90
90
|
Neste caso, a função `fakeFetch` simula um atraso para imitar o tempo de resposta do servidor. O Intlayer executa a função assíncrona e usa o resultado como o conteúdo para a chave `text`.
|
|
91
91
|
|
|
92
|
+
## Buscando Conteúdo Remoto
|
|
93
|
+
|
|
94
|
+
Você também pode atribuir uma promise diretamente a um campo de conteúdo. O Intlayer a aguarda durante a construção dos dicionários e insere o valor resolvido:
|
|
95
|
+
|
|
96
|
+
```typescript fileName="**/*.content.ts" contentDeclarationFormat={["typescript", "esm", "commonjs"]}
|
|
97
|
+
import type { Dictionary } from "intlayer";
|
|
98
|
+
|
|
99
|
+
const remoteContent = {
|
|
100
|
+
key: "remote_content",
|
|
101
|
+
content: {
|
|
102
|
+
externalContent: fetch("https://example.com").then((res) => res.json()),
|
|
103
|
+
},
|
|
104
|
+
} satisfies Dictionary;
|
|
105
|
+
|
|
106
|
+
export default remoteContent;
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
```plaintext fileName="**/*.content.json" contentDeclarationFormat="json"
|
|
110
|
+
Não é possível buscar conteúdo de um arquivo JSON, use um arquivo .ts ou .js em vez disso
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
> A requisição é executada em tempo de build, portanto os dados buscados são um instantâneo embutido no dicionário. Reconstrua seus dicionários para atualizá-los.
|
|
114
|
+
|
|
92
115
|
## Usando Conteúdo Baseado em Função em Componentes React
|
|
93
116
|
|
|
94
117
|
Para usar conteúdo baseado em função em um componente React, você precisa importar `useIntlayer` de `react-intlayer` e chamá-lo com o ID do conteúdo para recuperar o conteúdo. Aqui está um exemplo:
|
|
@@ -0,0 +1,336 @@
|
|
|
1
|
+
---
|
|
2
|
+
createdAt: 2026-08-12
|
|
3
|
+
updatedAt: 2026-08-13
|
|
4
|
+
title: Plugin ESLint | Regras de lint para o Intlayer
|
|
5
|
+
description: Detecte strings codificadas diretamente, chamadas dinâmicas que o compilador do Intlayer não consegue otimizar e conteúdo de dicionário não utilizado com eslint-plugin-intlayer. Compatível com ESLint e oxlint, no React, Vue, Svelte, Angular e Astro.
|
|
6
|
+
keywords:
|
|
7
|
+
- Intlayer
|
|
8
|
+
- ESLint
|
|
9
|
+
- oxlint
|
|
10
|
+
- Linting
|
|
11
|
+
- i18n
|
|
12
|
+
- Internacionalização
|
|
13
|
+
- no-raw-text
|
|
14
|
+
- Strings codificadas diretamente
|
|
15
|
+
- Traduções não utilizadas
|
|
16
|
+
- Conteúdo morto
|
|
17
|
+
- React
|
|
18
|
+
- Vue
|
|
19
|
+
- Svelte
|
|
20
|
+
- Angular
|
|
21
|
+
slugs:
|
|
22
|
+
- doc
|
|
23
|
+
- eslint
|
|
24
|
+
history:
|
|
25
|
+
- version: 9.3.1
|
|
26
|
+
date: 2026-08-12
|
|
27
|
+
changes: "Histórico inicial"
|
|
28
|
+
author: aymericzip
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
# Plugin ESLint x OXLint
|
|
32
|
+
|
|
33
|
+
O `eslint-plugin-intlayer` detecta os tipos de erros de i18n que o TypeScript não consegue identificar:
|
|
34
|
+
|
|
35
|
+
1. **Texto codificado diretamente (hardcoded)** que nunca chegou a um dicionário.
|
|
36
|
+
2. **Chamadas dinâmicas** que passam na verificação de tipos e são executadas, mas que o compilador do Intlayer não consegue otimizar.
|
|
37
|
+
3. **Conteúdo morto** — dicionários e campos que nada no projeto lê (ativação opcional).
|
|
38
|
+
|
|
39
|
+
Chaves de dicionário desconhecidas, caminhos de campos desconhecidos e idiomas ausentes já são erros de compilação, portanto o plugin não os repete.
|
|
40
|
+
|
|
41
|
+
## Instalação
|
|
42
|
+
|
|
43
|
+
```bash packageManager="npm"
|
|
44
|
+
npm install --save-dev eslint-plugin-intlayer
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
```bash packageManager="pnpm"
|
|
48
|
+
pnpm add --save-dev eslint-plugin-intlayer
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
```bash packageManager="yarn"
|
|
52
|
+
yarn add --dev eslint-plugin-intlayer
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Requer o ESLint 9 ou superior (flat config). O ESLint 10 é compatível.
|
|
56
|
+
|
|
57
|
+
## Utilização
|
|
58
|
+
|
|
59
|
+
O plugin funciona tanto no ESLint quanto no [oxlint](https://oxc.rs) — com as mesmas regras e as mesmas opções.
|
|
60
|
+
|
|
61
|
+
<Tabs defaultTab="eslint">
|
|
62
|
+
<Tab label="ESLint" value="eslint">
|
|
63
|
+
|
|
64
|
+
```javascript fileName="eslint.config.mjs"
|
|
65
|
+
import intlayer from "eslint-plugin-intlayer";
|
|
66
|
+
|
|
67
|
+
export default [...intlayer.configs.recommended];
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
Ou espalhe uma configuração e defina você mesmo as severidades:
|
|
71
|
+
|
|
72
|
+
```javascript fileName="eslint.config.mjs"
|
|
73
|
+
import intlayer from "eslint-plugin-intlayer";
|
|
74
|
+
|
|
75
|
+
export default [
|
|
76
|
+
...intlayer.configs.recommended,
|
|
77
|
+
{
|
|
78
|
+
rules: {
|
|
79
|
+
"intlayer/no-raw-text": "warn",
|
|
80
|
+
"intlayer/static-dictionary-key": "error",
|
|
81
|
+
"intlayer/no-dynamic-field-access": "error",
|
|
82
|
+
"intlayer/enforce-adapter-import": "warn",
|
|
83
|
+
"intlayer/no-unused-content": "warn",
|
|
84
|
+
},
|
|
85
|
+
},
|
|
86
|
+
];
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
</Tab>
|
|
90
|
+
<Tab label="oxlint" value="oxlint">
|
|
91
|
+
|
|
92
|
+
```json fileName=".oxlintrc.json"
|
|
93
|
+
{
|
|
94
|
+
"jsPlugins": ["eslint-plugin-intlayer"],
|
|
95
|
+
"rules": {
|
|
96
|
+
"intlayer/no-raw-text": "warn",
|
|
97
|
+
"intlayer/static-dictionary-key": "error",
|
|
98
|
+
"intlayer/no-dynamic-field-access": "error",
|
|
99
|
+
"intlayer/enforce-adapter-import": "warn"
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
Duas ressalvas: o suporte a plugins JS no oxlint ainda está em versão alfa e o oxlint não suporta parsers customizados — portanto, arquivos `.vue`, `.svelte`, `.astro` e templates do Angular não são verificados lá. Execute o oxlint nos seus arquivos JS/TS/JSX e mantenha o ESLint para o restante.
|
|
105
|
+
|
|
106
|
+
O `no-unused-content` foi omitido acima de propósito: ele precisa do diretório de trabalho e do caminho do arquivo analisado a partir do contexto da regra, o que a ponte alfa de plugins JS não garante. Execute-o no ESLint.
|
|
107
|
+
|
|
108
|
+
</Tab>
|
|
109
|
+
</Tabs>
|
|
110
|
+
|
|
111
|
+
### Configurações
|
|
112
|
+
|
|
113
|
+
| Configuração | `no-raw-text` | `static-dictionary-key` | `no-dynamic-field-access` | `enforce-adapter-import` | `no-unused-content` |
|
|
114
|
+
| --------------- | ------------------------------ | ----------------------- | ------------------------- | ------------------------ | ------------------- |
|
|
115
|
+
| `recommended` | warn | error | error | off | off |
|
|
116
|
+
| `strict` | error (+ literais fora de JSX) | error | error | error | off |
|
|
117
|
+
| `contract-only` | off | error | error | off | off |
|
|
118
|
+
|
|
119
|
+
A configuração `recommended` mantém deliberadamente `no-raw-text` como `warn`: apontá-la para uma base de código existente traz à tona todas as strings não traduzidas de uma só vez, o que não deve quebrar a sua compilação logo no primeiro dia.
|
|
120
|
+
|
|
121
|
+
O `enforce-adapter-import` fica desativado por padrão — ative-o explicitamente se desejar.
|
|
122
|
+
|
|
123
|
+
O `no-unused-content` fica desativado em todas as configurações, inclusive na `strict`. É a única regra que lê sua configuração do Intlayer e percorre seus arquivos de código no disco; portanto, ativá-la deve ser uma escolha consciente e não algo imposto por uma predefinição.
|
|
124
|
+
|
|
125
|
+
## Regras
|
|
126
|
+
|
|
127
|
+
### `no-raw-text`
|
|
128
|
+
|
|
129
|
+
Reporta texto voltado ao usuário que não esteja declarado em um dicionário. Ele usa a mesma detecção do `intlayer extract`, portanto nomes de marcas, classes CSS e identificadores técnicos são ignorados.
|
|
130
|
+
|
|
131
|
+
```jsx
|
|
132
|
+
// ✗ Reportado
|
|
133
|
+
<h1>Welcome to our documentation</h1>
|
|
134
|
+
<input placeholder="Enter your email address" />
|
|
135
|
+
|
|
136
|
+
// ✓ Correto
|
|
137
|
+
const { title } = useIntlayer("home");
|
|
138
|
+
<h1>{title}</h1>
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
Arquivos de declaração de conteúdo (`*.content.ts`, …) são ignorados.
|
|
142
|
+
|
|
143
|
+
Para corrigir um arquivo inteiro de uma só vez, execute `npx intlayer extract` e deixe o compilador mover as strings para um dicionário para você.
|
|
144
|
+
|
|
145
|
+
**Opções**
|
|
146
|
+
|
|
147
|
+
```javascript fileName="eslint.config.mjs"
|
|
148
|
+
{
|
|
149
|
+
"intlayer/no-raw-text": [
|
|
150
|
+
"warn",
|
|
151
|
+
{
|
|
152
|
+
// Atributos cujo valor é texto voltado ao usuário.
|
|
153
|
+
// Padrão: title, placeholder, alt, aria-label, label
|
|
154
|
+
attributes: ["title", "placeholder", "alt", "aria-label", "label"],
|
|
155
|
+
|
|
156
|
+
// Elementos cujo conteúdo nunca é texto voltado ao usuário.
|
|
157
|
+
// Padrão: code, pre, script, style
|
|
158
|
+
ignoreElements: ["code", "pre", "script", "style"],
|
|
159
|
+
|
|
160
|
+
// Expressões regulares para textos que nunca devem ser reportados.
|
|
161
|
+
ignorePatterns: ["^Powered by"],
|
|
162
|
+
|
|
163
|
+
// Também reportar literais de string fora do markup. Padrão: false
|
|
164
|
+
includeStringLiterals: false,
|
|
165
|
+
},
|
|
166
|
+
],
|
|
167
|
+
}
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
### `static-dictionary-key`
|
|
171
|
+
|
|
172
|
+
Exige que a chave do dicionário seja uma string literal.
|
|
173
|
+
|
|
174
|
+
O compilador só consegue pré-carregar um dicionário quando pode ler a chave diretamente no local da chamada. Com uma chave calculada, ele pula silenciosamente a otimização e inclui todos os dicionários no bundle.
|
|
175
|
+
|
|
176
|
+
```typescript
|
|
177
|
+
// ✗ Reportado
|
|
178
|
+
useIntlayer(dictionaryKey);
|
|
179
|
+
useIntlayer(`home-${suffix}`);
|
|
180
|
+
getTranslations({ namespace: page });
|
|
181
|
+
|
|
182
|
+
// ✗ Uma variável ainda não é um literal
|
|
183
|
+
const key = "home";
|
|
184
|
+
useIntlayer(key);
|
|
185
|
+
|
|
186
|
+
// ✓ Correto
|
|
187
|
+
useIntlayer("home");
|
|
188
|
+
getTranslations({ namespace: "home" });
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
Isso se aplica ao `useIntlayer`, `getIntlayer` e a todos os adaptadores de compatibilidade (`useTranslation`, `useTranslations`, `formatMessage`, `<FormattedMessage id>`, `<Trans i18nKey>`, …).
|
|
192
|
+
|
|
193
|
+
### `no-dynamic-field-access`
|
|
194
|
+
|
|
195
|
+
Exige que o campo lido de um dicionário seja conhecido estaticamente.
|
|
196
|
+
|
|
197
|
+
O compilador remove campos que não são identificados como utilizados. Um acesso computado é invisível para ele, portanto a leitura pode retornar `undefined` em tempo de execução.
|
|
198
|
+
|
|
199
|
+
```typescript
|
|
200
|
+
// ✗ Reportado
|
|
201
|
+
const content = useIntlayer("home");
|
|
202
|
+
content[fieldName];
|
|
203
|
+
|
|
204
|
+
const t = useTranslations("home");
|
|
205
|
+
t(messageKey);
|
|
206
|
+
|
|
207
|
+
// ✓ Correto
|
|
208
|
+
content.title;
|
|
209
|
+
content["title"];
|
|
210
|
+
content.items[0];
|
|
211
|
+
t("hero.title");
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
### `enforce-adapter-import`
|
|
215
|
+
|
|
216
|
+
Prefere o adaptador de compatibilidade `@intlayer/*` ao pacote original. O original só é resolvido para o Intlayer quando o alias do empacotador está configurado; o adaptador sempre funciona. Corrigível automaticamente com `--fix`.
|
|
217
|
+
|
|
218
|
+
```typescript
|
|
219
|
+
// ✗ Reportado
|
|
220
|
+
import { useTranslation } from "react-i18next";
|
|
221
|
+
import { getTranslations } from "next-intl/server";
|
|
222
|
+
|
|
223
|
+
// ✓ Correto
|
|
224
|
+
import { useTranslation } from "@intlayer/react-i18next";
|
|
225
|
+
import { getTranslations } from "@intlayer/next-intl/server";
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
### `no-unused-content`
|
|
229
|
+
|
|
230
|
+
**Desativada por padrão.** Reporta conteúdo que nada em seu projeto lê, além de chaves de dicionário declaradas em mais de um local.
|
|
231
|
+
|
|
232
|
+
```typescript fileName="src/home.content.ts"
|
|
233
|
+
export default {
|
|
234
|
+
key: "home", // ✗ Reportado se nenhum chamador no projeto solicitar "home"
|
|
235
|
+
content: {
|
|
236
|
+
title: t({ pt: "Título", en: "Title" }),
|
|
237
|
+
|
|
238
|
+
// ✗ Reportado se nada ler `hero`
|
|
239
|
+
hero: {
|
|
240
|
+
subtitle: t({ pt: "Subtítulo", en: "Subtitle" }),
|
|
241
|
+
},
|
|
242
|
+
},
|
|
243
|
+
};
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
Ao contrário das outras regras, esta não pode responder apenas com base no arquivo analisado — um campo só é considerado não utilizado em relação ao projeto inteiro. Na primeira declaração de conteúdo de uma execução do linter, ela carrega a sua configuração do Intlayer, busca os arquivos de código declarados por essa configuração (`build.traversePattern`, `compiler.transformPattern`) e executa o mesmo analisador de uso que alimenta o `@intlayer/lsp` e o tachado de "não utilizado" na extensão do VS Code. O resultado é armazenado em cache por `cacheTtl` milissegundos, para que a varredura ocorra uma vez por execução e não a cada arquivo.
|
|
247
|
+
|
|
248
|
+
**Opções**
|
|
249
|
+
|
|
250
|
+
```javascript fileName="eslint.config.mjs"
|
|
251
|
+
{
|
|
252
|
+
"intlayer/no-unused-content": [
|
|
253
|
+
"warn",
|
|
254
|
+
{
|
|
255
|
+
// Reportar chaves de dicionário que nada referencia. Padrão: true
|
|
256
|
+
reportUnusedDictionaries: true,
|
|
257
|
+
|
|
258
|
+
// Reportar campos de conteúdo que nada lê. Padrão: true
|
|
259
|
+
reportUnusedFields: true,
|
|
260
|
+
|
|
261
|
+
// Reportar chaves declaradas em mais de um lugar. Padrão: true
|
|
262
|
+
reportDuplicateKeys: true,
|
|
263
|
+
|
|
264
|
+
// Expressões regulares para caminhos de campos que nunca devem ser reportados.
|
|
265
|
+
ignoreFields: ["^meta"],
|
|
266
|
+
|
|
267
|
+
// Raiz do projeto a partir de onde a verificação começa. Padrão: diretório de trabalho do ESLint
|
|
268
|
+
baseDir: process.cwd(),
|
|
269
|
+
|
|
270
|
+
// Tempo de reutilização de uma varredura de projeto, em ms. Padrão: 30000
|
|
271
|
+
cacheTtl: 30000,
|
|
272
|
+
},
|
|
273
|
+
],
|
|
274
|
+
}
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
Diminua `cacheTtl` ao executar o lint a partir de um servidor de editor de longa duração e quiser que as alterações apareçam mais rápido; defina `baseDir` quando uma única execução de lint cobrir vários projetos Intlayer em um monorepo.
|
|
278
|
+
|
|
279
|
+
> **Tende ao silêncio.** Um falso positivo aqui apagaria uma tradução; portanto, nada é reportado quando o dicionário é consumido de uma forma que a análise não consiga rastrear: o objeto de conteúdo passado por completo, uma função de tradução vinculada a partir dele (`const t = useTranslations("home")`), uma declaração acessada por importação direta (`useDictionary(myDictionary)`), um `nest()` de outro dicionário ou uma lista de campos tornada não exaustiva por um spread. Componentes de arquivo único (`.vue`, `.svelte`, `.astro`) são considerados como usuários de todos os campos dos dicionários mencionados, pois seus blocos de script não são analisados aqui.
|
|
280
|
+
|
|
281
|
+
O `reportDuplicateKeys` lê os dicionários não mesclados que o build grava em `.intlayer/`, portanto permanece em silêncio até que o projeto tenha sido construído pelo menos uma vez. Duas declarações compartilhando uma chave são mescladas, o que é um padrão válido — o aviso existe porque um campo definido em ambos os lados mantém silenciosamente apenas um dos dois valores.
|
|
282
|
+
|
|
283
|
+
O analisador é carregado a partir do `@intlayer/lsp`, distribuído como ESM. A regra requer, portanto, uma versão do Node compatível com `require()` em módulos ES — Node 20.19+ ou 22.12+. Em versões anteriores, ela não reporta nada em vez de falhar a execução do lint.
|
|
284
|
+
|
|
285
|
+
## Frameworks
|
|
286
|
+
|
|
287
|
+
Todas as regras funcionam em todas as integrações do Intlayer, inclusive dentro de templates Vue, Svelte e Angular. Você só precisa informar ao ESLint qual parser lê cada tipo de arquivo.
|
|
288
|
+
|
|
289
|
+
| Framework | Arquivos | Parser |
|
|
290
|
+
| ------------------------- | ----------------- | --------------------------------- |
|
|
291
|
+
| React, Preact, Solid, Lit | `.jsx` `.tsx` | `typescript-eslint` |
|
|
292
|
+
| Next.js | `.jsx` `.tsx` | `typescript-eslint` |
|
|
293
|
+
| Vue, Nuxt | `.vue` | `vue-eslint-parser` |
|
|
294
|
+
| Svelte, SvelteKit | `.svelte` | `svelte-eslint-parser` |
|
|
295
|
+
| Angular | `.ts` | `typescript-eslint` |
|
|
296
|
+
| Templates do Angular | `.component.html` | `@angular-eslint/template-parser` |
|
|
297
|
+
| Astro | `.astro` | `astro-eslint-parser` |
|
|
298
|
+
|
|
299
|
+
```javascript fileName="eslint.config.mjs"
|
|
300
|
+
import intlayer from "eslint-plugin-intlayer";
|
|
301
|
+
import tseslint from "typescript-eslint";
|
|
302
|
+
import vueParser from "vue-eslint-parser";
|
|
303
|
+
import svelteParser from "svelte-eslint-parser";
|
|
304
|
+
import angularTemplateParser from "@angular-eslint/template-parser";
|
|
305
|
+
|
|
306
|
+
export default [
|
|
307
|
+
...intlayer.configs.recommended,
|
|
308
|
+
|
|
309
|
+
{
|
|
310
|
+
files: ["**/*.{ts,tsx,jsx}"],
|
|
311
|
+
languageOptions: { parser: tseslint.parser },
|
|
312
|
+
},
|
|
313
|
+
{
|
|
314
|
+
files: ["**/*.vue"],
|
|
315
|
+
languageOptions: {
|
|
316
|
+
parser: vueParser,
|
|
317
|
+
parserOptions: { parser: tseslint.parser },
|
|
318
|
+
},
|
|
319
|
+
},
|
|
320
|
+
{
|
|
321
|
+
files: ["**/*.svelte"],
|
|
322
|
+
languageOptions: {
|
|
323
|
+
parser: svelteParser,
|
|
324
|
+
parserOptions: { parser: tseslint.parser },
|
|
325
|
+
},
|
|
326
|
+
},
|
|
327
|
+
{
|
|
328
|
+
files: ["**/*.component.html"],
|
|
329
|
+
languageOptions: { parser: angularTemplateParser },
|
|
330
|
+
},
|
|
331
|
+
];
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
Instale apenas os parsers de que seu projeto precisa.
|
|
335
|
+
|
|
336
|
+
> **Limitação conhecida.** Em templates do Vue e Angular, uma expressão como `{{ content[key] }}` não é verificada pelo `no-dynamic-field-access`. Leituras dinâmicas escritas no bloco script são identificadas normalmente.
|
|
@@ -317,120 +317,7 @@ A integração do Astro adiciona um middleware Vite que ajuda no roteamento sens
|
|
|
317
317
|
|
|
318
318
|
</Step>
|
|
319
319
|
|
|
320
|
-
<Step number={
|
|
321
|
-
|
|
322
|
-
Continue construindo sua aplicação usando o framework de sua escolha.
|
|
323
|
-
|
|
324
|
-
- Intlayer + React: [Intlayer com React](https://github.com/aymericzip/intlayer/blob/main/docs/docs/pt/intlayer_with_vite+react.md)
|
|
325
|
-
- Intlayer + Vue: [Intlayer com Vue](https://github.com/aymericzip/intlayer/blob/main/docs/docs/pt/intlayer_with_vite+vue.md)
|
|
326
|
-
- Intlayer + Svelte: [Intlayer com Svelte](https://github.com/aymericzip/intlayer/blob/main/docs/docs/pt/intlayer_with_vite+svelte.md)
|
|
327
|
-
- Intlayer + Solid: [Intlayer com Solid](https://github.com/aymericzip/intlayer/blob/main/docs/docs/pt/intlayer_with_vite+solid.md)
|
|
328
|
-
- Intlayer + Preact: [Intlayer com Preact](https://github.com/aymericzip/intlayer/blob/main/docs/docs/pt/intlayer_with_vite+preact.md)
|
|
329
|
-
</Step>
|
|
330
|
-
|
|
331
|
-
<Step number={15} title="Extrair o conteúdo dos seus componentes" isOptional={true}>
|
|
332
|
-
|
|
333
|
-
Se você tiver uma base de código existente, transformar milhares de arquivos pode ser demorado.
|
|
334
|
-
|
|
335
|
-
Para facilitar esse processo, o Intlayer propõe um [compilador](https://github.com/aymericzip/intlayer/blob/main/docs/docs/pt/compiler.md) / [extrator](https://github.com/aymericzip/intlayer/blob/main/docs/docs/pt/cli/extract.md) para transformar seus componentes e extrair o conteúdo.
|
|
336
|
-
|
|
337
|
-
Para configurá-lo, você pode adicionar uma seção `compiler` no seu arquivo `intlayer.config.ts`:
|
|
338
|
-
|
|
339
|
-
```typescript fileName="intlayer.config.ts" codeFormat={["typescript", "esm", "commonjs"]}
|
|
340
|
-
import { type IntlayerConfig } from "intlayer";
|
|
341
|
-
|
|
342
|
-
const config: IntlayerConfig = {
|
|
343
|
-
// ... Resto da sua configuração
|
|
344
|
-
compiler: {
|
|
345
|
-
/**
|
|
346
|
-
* Indica se o compilador deve ser ativado.
|
|
347
|
-
*/
|
|
348
|
-
enabled: true,
|
|
349
|
-
|
|
350
|
-
/**
|
|
351
|
-
* Define o caminho dos arquivos de saída
|
|
352
|
-
*/
|
|
353
|
-
output: ({ fileName, extension }) => `./${fileName}${extension}`,
|
|
354
|
-
|
|
355
|
-
/**
|
|
356
|
-
* Indica se os componentes devem ser salvos após serem transformados. Dessa forma, o compilador pode ser executado apenas uma vez para transformar o aplicativo e depois removido.
|
|
357
|
-
*/
|
|
358
|
-
saveComponents: false,
|
|
359
|
-
|
|
360
|
-
/**
|
|
361
|
-
* Prefixo da chave do dicionário
|
|
362
|
-
*/
|
|
363
|
-
dictionaryKeyPrefix: "",
|
|
364
|
-
},
|
|
365
|
-
};
|
|
366
|
-
|
|
367
|
-
export default config;
|
|
368
|
-
```
|
|
369
|
-
|
|
370
|
-
<Tabs>
|
|
371
|
-
<Tab value='Comando de extração'>
|
|
372
|
-
|
|
373
|
-
Execute o extrator para transformar seus componentes e extrair o conteúdo
|
|
374
|
-
|
|
375
|
-
```bash packageManager="npm"
|
|
376
|
-
npx intlayer extract
|
|
377
|
-
```
|
|
378
|
-
|
|
379
|
-
```bash packageManager="pnpm"
|
|
380
|
-
pnpm intlayer extract
|
|
381
|
-
```
|
|
382
|
-
|
|
383
|
-
```bash packageManager="yarn"
|
|
384
|
-
yarn intlayer extract
|
|
385
|
-
```
|
|
386
|
-
|
|
387
|
-
```bash packageManager="bun"
|
|
388
|
-
bun x intlayer extract
|
|
389
|
-
```
|
|
390
|
-
|
|
391
|
-
</Tab>
|
|
392
|
-
<Tab value='Compilador Babel'>
|
|
393
|
-
|
|
394
|
-
> Since v9, the `intlayerCompiler` is included in the `intlayer` plugin. So you don't need to add it manually.
|
|
395
|
-
|
|
396
|
-
Atualize seu `vite.config.ts` para incluir o plugin `intlayerCompiler`:
|
|
397
|
-
|
|
398
|
-
```ts fileName="vite.config.ts"
|
|
399
|
-
import { defineConfig } from "vite";
|
|
400
|
-
import { intlayer, intlayerCompiler } from "vite-intlayer";
|
|
401
|
-
|
|
402
|
-
export default defineConfig({
|
|
403
|
-
plugins: [
|
|
404
|
-
intlayer(),
|
|
405
|
-
intlayerCompiler(), // Adds the compiler plugin
|
|
406
|
-
],
|
|
407
|
-
});
|
|
408
|
-
```
|
|
409
|
-
|
|
410
|
-
```bash packageManager="npm"
|
|
411
|
-
npm run build # Ou npm run dev
|
|
412
|
-
```
|
|
413
|
-
|
|
414
|
-
```bash packageManager="pnpm"
|
|
415
|
-
pnpm run build # Or pnpm run dev
|
|
416
|
-
```
|
|
417
|
-
|
|
418
|
-
```bash packageManager="yarn"
|
|
419
|
-
yarn build # Or yarn dev
|
|
420
|
-
```
|
|
421
|
-
|
|
422
|
-
```bash packageManager="bun"
|
|
423
|
-
bun run build # Or bun run dev
|
|
424
|
-
```
|
|
425
|
-
|
|
426
|
-
</Tab>
|
|
427
|
-
</Tabs>
|
|
428
|
-
|
|
429
|
-
---
|
|
430
|
-
|
|
431
|
-
</Step>
|
|
432
|
-
|
|
433
|
-
</Steps>
|
|
320
|
+
<Step number={8} title="Sitemap e Robots.txt">
|
|
434
321
|
|
|
435
322
|
#### Sitemap
|
|
436
323
|
|
|
@@ -159,7 +159,7 @@ pnpm add -D webpack-bundle-analyzer
|
|
|
159
159
|
bun add -d webpack-bundle-analyzer
|
|
160
160
|
```
|
|
161
161
|
|
|
162
|
-
```typescript fileName="webpack.config.ts
|
|
162
|
+
```typescript fileName="webpack.config.ts"
|
|
163
163
|
import { BundleAnalyzerPlugin } from "webpack-bundle-analyzer";
|
|
164
164
|
|
|
165
165
|
export default {
|