diff --git a/locales/en.yml b/locales/en.yml
index 4982dc53..0feb50b4 100644
--- a/locales/en.yml
+++ b/locales/en.yml
@@ -1,3 +1,26 @@
home:
+ commandPalette:
+ search: Search...
+ placeholder: Type to search a tool or a command...
+ commandPaletteStore:
+ actions: Actions
+ external: External
+ tools: Tools
categories:
- newestTools: "Newest tools"
+ newestTools: Newest tools
+ title: IT Tools - Handy online tools for developers
+ allTools: All the tools
+ favoriteTools: Your favorite tools
+ thanks: '! Thank you'
+ giveUsAStarOn: Give us a star on
+ orFollowUsOn: or follow us on
+ youLikeItTools: You like it-tools?
+tools:
+ xmlFormat:
+ description: Prettify your XML string to a human friendly readable format.
+ indentSize: 'Indent size:'
+ collapseContent: 'Collapse content:'
+ providedXmlIsNotValid: Provided XML is not valid.
+ inputLabel: Your XML
+ outputLabel: Formatted XML from your XML
+ placeHolder: Paste your XML here...
diff --git a/locales/es.yml b/locales/es.yml
new file mode 100644
index 00000000..855d4f45
--- /dev/null
+++ b/locales/es.yml
@@ -0,0 +1,26 @@
+home:
+ commandPalette:
+ search: Buscar...
+ placeholder: Escribe para buscar una herramienta o comando...
+ commandPaletteStore:
+ actions: Acciones
+ external: Externa
+ tools: Herramientas
+ categories:
+ newestTools: Herramientas Nuevas
+ title: 'IT Tools - Prácticas herramientas en línea para desarrolladores.'
+ allTools: Todas las herramientas
+ favoriteTools: Tus herramientas favorias
+ thanks: '! Thank you'
+ giveUsAStarOn: Give us a star on
+ orFollowUsOn: or follow us on
+ youLikeItTools: You like it-tools?
+tools:
+ xmlFormat:
+ description: Embellece tu XML a un formato XML más amigable.
+ indentSize: 'Tamaño de indentación:'
+ collapseContent: 'Colapsar contenido:'
+ providedXmlIsNotValid: El XML proporcionado no es válido.
+ inputLabel: Tu XML
+ outputLabel: XML Formateado desde tu XML
+ placeHolder: Pega tu XML aquí...
diff --git a/src/components/ToolCard.vue b/src/components/ToolCard.vue
index 00f22466..5ffeae96 100644
--- a/src/components/ToolCard.vue
+++ b/src/components/ToolCard.vue
@@ -8,6 +8,8 @@ const props = defineProps<{ tool: Tool & { category: string } }>();
const { tool } = toRefs(props);
const theme = useThemeVars();
+const { t } = useI18n();
+
const appTheme = useAppTheme();
@@ -38,7 +40,7 @@ const appTheme = useAppTheme();
- {{ tool.description }}
+ {{ t(tool.description) }}
diff --git a/src/layouts/base.layout.vue b/src/layouts/base.layout.vue
index 36edd77d..a80505ff 100644
--- a/src/layouts/base.layout.vue
+++ b/src/layouts/base.layout.vue
@@ -7,6 +7,7 @@ import { Heart, Home2, Menu2 } from '@vicons/tabler';
import HeroGradient from '../assets/hero-gradient.svg?component';
import MenuLayout from '../components/MenuLayout.vue';
import NavbarButtons from '../components/NavbarButtons.vue';
+import { availableLocales, loadLanguageAsync } from '../plugins/i18n.plugin';
import { toolsByCategory } from '@/tools';
import { useStyleStore } from '@/stores/style.store';
import { config } from '@/config';
@@ -24,10 +25,19 @@ const { tracker } = useTracker();
const toolStore = useToolStore();
+const currentLang = useStorage('application:selected-language', 'en');
+
+loadLanguageAsync(currentLang.value);
+
const tools = computed(() => [
...(toolStore.favoriteTools.length > 0 ? [{ name: 'Your favorite tools', components: toolStore.favoriteTools }] : []),
...toolsByCategory,
]);
+
+function onChange(event: any) {
+ currentLang.value = event;
+ loadLanguageAsync(event);
+}
@@ -106,6 +116,15 @@ const tools = computed(() => [
+
+
@@ -223,4 +242,7 @@ const tools = computed(() => [
flex-grow: 1;
}
}
+.i18n{
+ width: 75px;
+}
diff --git a/src/layouts/tool.layout.vue b/src/layouts/tool.layout.vue
index bdbb8695..1279646c 100644
--- a/src/layouts/tool.layout.vue
+++ b/src/layouts/tool.layout.vue
@@ -9,6 +9,7 @@ import type { Tool } from '@/tools/tools.types';
const route = useRoute();
+const { t } = useI18n();
const head = computed(() => ({
title: `${route.meta.name} - IT Tools`,
meta: [
@@ -42,7 +43,7 @@ useHead(head);
- {{ route.meta.description }}
+ {{ t(route.meta.description) }}
diff --git a/src/modules/command-palette/command-palette.store.ts b/src/modules/command-palette/command-palette.store.ts
index f2153884..2348187f 100644
--- a/src/modules/command-palette/command-palette.store.ts
+++ b/src/modules/command-palette/command-palette.store.ts
@@ -18,7 +18,7 @@ export const useCommandPaletteStore = defineStore('command-palette', () => {
...tool,
to: tool.path,
toolCategory: tool.category,
- category: 'Tools',
+ category: 'home.commandPaletteStore.tools',
}));
const searchOptions: PaletteOption[] = [
@@ -28,13 +28,13 @@ export const useCommandPaletteStore = defineStore('command-palette', () => {
description: 'Toggle dark mode on or off.',
action: () => styleStore.toggleDark(),
icon: SunIcon,
- category: 'Actions',
+ category: 'home.commandPaletteStore.actions',
keywords: ['dark', 'theme', 'toggle', 'mode', 'light', 'system'],
},
{
name: 'Github repository',
href: 'https://github.com/CorentinTh/it-tools',
- category: 'External',
+ category: 'home.commandPaletteStore.external',
description: 'View the source code of it-tools on Github.',
keywords: ['github', 'repo', 'repository', 'source', 'code'],
icon: GithubIcon,
@@ -43,7 +43,7 @@ export const useCommandPaletteStore = defineStore('command-palette', () => {
name: 'Report a bug or an issue',
description: 'Report a bug or an issue to help improve it-tools.',
href: 'https://github.com/CorentinTh/it-tools/issues/new/choose',
- category: 'Actions',
+ category: 'home.commandPaletteStore.actions',
keywords: ['report', 'issue', 'bug', 'problem', 'error'],
icon: BugIcon,
},
@@ -59,7 +59,11 @@ export const useCommandPaletteStore = defineStore('command-palette', () => {
});
const filteredSearchResult = computed(() =>
- _.chain(searchResult.value).groupBy('category').mapValues(categoryOptions => _.take(categoryOptions, 5)).value());
+ _.chain(searchResult.value)
+ .groupBy('category')
+ .mapValues(categoryOptions => _.take(categoryOptions, 5))
+ .value(),
+ );
return {
filteredSearchResult,
diff --git a/src/modules/command-palette/command-palette.vue b/src/modules/command-palette/command-palette.vue
index bd431a02..b12e7bf9 100644
--- a/src/modules/command-palette/command-palette.vue
+++ b/src/modules/command-palette/command-palette.vue
@@ -9,6 +9,8 @@ const inputRef = ref();
const router = useRouter();
const isMac = computed(() => window.navigator.userAgent.toLowerCase().includes('mac'));
+const { t } = useI18n();
+
const commandPaletteStore = useCommandPaletteStore();
const { searchPrompt, filteredSearchResult } = storeToRefs(commandPaletteStore);
@@ -99,7 +101,7 @@ function activateOption(option: PaletteOption) {
- Search...
+ {{ t('home.commandPalette.search') }}
{{ isMac ? 'Cmd' : 'Ctrl' }} + K
@@ -108,11 +110,11 @@ function activateOption(option: PaletteOption) {
-
+
- {{ category }}
+ {{ t(category) }}
diff --git a/src/modules/command-palette/components/command-palette-option.vue b/src/modules/command-palette/components/command-palette-option.vue
index 9192bc04..b381b8ba 100644
--- a/src/modules/command-palette/components/command-palette-option.vue
+++ b/src/modules/command-palette/components/command-palette-option.vue
@@ -8,6 +8,7 @@ const emit = defineEmits(['activated']);
const { option } = toRefs(props);
const { selected } = toRefs(props);
+const { t } = useI18n();
@@ -29,7 +30,7 @@ const { selected } = toRefs(props);
- {{ option.description }}
+ {{ t(option.description) }}
diff --git a/src/pages/Home.page.vue b/src/pages/Home.page.vue
index 5c7c3c4f..409809d1 100644
--- a/src/pages/Home.page.vue
+++ b/src/pages/Home.page.vue
@@ -7,9 +7,9 @@ import { useToolStore } from '@/tools/tools.store';
import { config } from '@/config';
const toolStore = useToolStore();
-
-useHead({ title: 'IT Tools - Handy online tools for developers' });
const { t } = useI18n();
+const title = t('home.categories.title');
+useHead({ title });
@@ -17,29 +17,28 @@ const { t } = useI18n();
-
- Give us a star on
+
+ t('home.categories.giveUsAStarOn')
GitHub
- or follow us on
+ t('home.categories.orFollowUsOn')
Twitter! Thank you
+ >Twittert('home.categories.thanks')
-
- Your favorite tools
+ {{ t('home.categories.favoriteTools') }}
@@ -57,7 +56,7 @@ const { t } = useI18n();
- All the tools
+ {{ t('home.categories.allTools') }}
diff --git a/src/tools/xml-formatter/index.ts b/src/tools/xml-formatter/index.ts
index fe28d3ae..dd9d4851 100644
--- a/src/tools/xml-formatter/index.ts
+++ b/src/tools/xml-formatter/index.ts
@@ -4,7 +4,7 @@ import { defineTool } from '../tool';
export const tool = defineTool({
name: 'XML formatter',
path: '/xml-formatter',
- description: 'Prettify your XML string to a human friendly readable format.',
+ description: 'tools.xmlFormat.description',
keywords: ['xml', 'prettify', 'format'],
component: () => import('./xml-formatter.vue'),
icon: Code,
diff --git a/src/tools/xml-formatter/xml-formatter.vue b/src/tools/xml-formatter/xml-formatter.vue
index d59cf8c7..09a8c618 100644
--- a/src/tools/xml-formatter/xml-formatter.vue
+++ b/src/tools/xml-formatter/xml-formatter.vue
@@ -2,6 +2,8 @@
import { formatXml, isValidXML } from './xml-formatter.service';
import type { UseValidationRule } from '@/composable/validation';
+const { t } = useI18n();
+
const defaultValue = 'foobar';
const indentSize = useStorage('xml-formatter:indent-size', 2);
const collapseContent = useStorage('xml-formatter:collapse-content', true);
@@ -17,7 +19,7 @@ function transformer(value: string) {
const rules: UseValidationRule[] = [
{
validator: isValidXML,
- message: 'Provided XML is not valid.',
+ message: t('tools.xmlFormat.providedXmlIsNotValid'),
},
];
@@ -25,19 +27,19 @@ const rules: UseValidationRule[] = [