diff --git a/src/tools/hash-text/locales/zh.yml b/src/tools/hash-text/locales/zh.yml
index 66363a71..9dcc9c4f 100644
--- a/src/tools/hash-text/locales/zh.yml
+++ b/src/tools/hash-text/locales/zh.yml
@@ -1,12 +1,12 @@
 tools:
   hash-text:
     title: 文本转哈希
-    description: 使用所需的函数对文本字符串进行哈希计算:MD5、SHA1、SHA256、SHA224、SHA512、SHA384、SHA3或RIPEMD160
+    description: '使用所需的函数对文本字符串进行哈希计算:MD5、SHA1、SHA256、SHA224、SHA512、SHA384、SHA3或RIPEMD160'
 
     textLabel: '要进行哈希的文本:'
     textPlaceholder: '要进行哈希的字符串...'
-    hashLabel: 摘要编码
-    binary: 二进制(基数2)
-    hexadecimal: 十六进制(基数16)
-    base64: Base64(基数64)
-    base64url: Base64url(带有URL安全字符的基数64)
+    hashLabel: '摘要编码'
+    binary: '二进制(基数2)'
+    hexadecimal: '十六进制(基数16)'
+    base64: 'Base64(基数64)'
+    base64url: 'Base64url(带有URL安全字符的基数64)'
diff --git a/src/tools/html-entities/locales/en.yml b/src/tools/html-entities/locales/en.yml
index b37b45cd..aaaf0ea4 100644
--- a/src/tools/html-entities/locales/en.yml
+++ b/src/tools/html-entities/locales/en.yml
@@ -1,7 +1,7 @@
 tools:
   html-entities:
     title: Escape html entities
-    description: Escape or unescape html entities (replace <,>, &, " and \' to their html version)
+    description: Escape or unescape html entities (replace <,>, &, " and ' to their html version)
 
     escape:
       title: Escape html entities
diff --git a/src/tools/html-entities/locales/zh.yml b/src/tools/html-entities/locales/zh.yml
index 35b8062e..4288d852 100644
--- a/src/tools/html-entities/locales/zh.yml
+++ b/src/tools/html-entities/locales/zh.yml
@@ -1,7 +1,7 @@
 tools:
   html-entities:
     title: 转义 HTML 实体
-    description: 转义或取消转义 HTML 实体(将 <,>, &, " 和 \' 替换为它们的 HTML 版本)
+    description: 转义或取消转义 HTML 实体(将 <,>, &, " 和 ' 替换为它们的 HTML 版本)
 
     escape:
       title: 转义 HTML 实体
diff --git a/src/tools/html-wysiwyg-editor/editor/menu-bar.vue b/src/tools/html-wysiwyg-editor/editor/menu-bar.vue
index d3ad3168..cc3079c6 100644
--- a/src/tools/html-wysiwyg-editor/editor/menu-bar.vue
+++ b/src/tools/html-wysiwyg-editor/editor/menu-bar.vue
@@ -20,6 +20,7 @@ import {
 } from '@vicons/tabler';
 import type { Component } from 'vue';
 import MenuBarItem from './menu-bar-item.vue';
+import { translate as t } from '@/plugins/i18n.plugin';
 
 const props = defineProps<{ editor: Editor }>();
 const { editor } = toRefs(props);
@@ -38,28 +39,28 @@ const items: MenuItem[] = [
   {
     type: 'button',
     icon: Bold,
-    title: 'Bold',
+    title: t('tools.html-wysiwyg-editor.bold'),
     action: () => editor.value.chain().focus().toggleBold().run(),
     isActive: () => editor.value.isActive('bold'),
   },
   {
     type: 'button',
     icon: Italic,
-    title: 'Italic',
+    title: t('tools.html-wysiwyg-editor.italic'),
     action: () => editor.value.chain().focus().toggleItalic().run(),
     isActive: () => editor.value.isActive('italic'),
   },
   {
     type: 'button',
     icon: Strikethrough,
-    title: 'Strike',
+    title: t('tools.html-wysiwyg-editor.strike'),
     action: () => editor.value.chain().focus().toggleStrike().run(),
     isActive: () => editor.value.isActive('strike'),
   },
   {
     type: 'button',
     icon: Code,
-    title: 'Inline code',
+    title: t('tools.html-wysiwyg-editor.inlineCode'),
     action: () => editor.value.chain().focus().toggleCode().run(),
     isActive: () => editor.value.isActive('code'),
   },
@@ -69,28 +70,28 @@ const items: MenuItem[] = [
   {
     type: 'button',
     icon: H1,
-    title: 'Heading 1',
+    title: t('tools.html-wysiwyg-editor.heading1'),
     action: () => editor.value.chain().focus().toggleHeading({ level: 1 }).run(),
     isActive: () => editor.value.isActive('heading', { level: 1 }),
   },
   {
     type: 'button',
     icon: H2,
-    title: 'Heading 2',
+    title: t('tools.html-wysiwyg-editor.heading2'),
     action: () => editor.value.chain().focus().toggleHeading({ level: 2 }).run(),
     isActive: () => editor.value.isActive('heading', { level: 2 }),
   },
   {
     type: 'button',
     icon: H3,
-    title: 'Heading 3',
+    title: t('tools.html-wysiwyg-editor.heading3'),
     action: () => editor.value.chain().focus().toggleHeading({ level: 4 }).run(),
     isActive: () => editor.value.isActive('heading', { level: 4 }),
   },
   {
     type: 'button',
     icon: H4,
-    title: 'Heading 4',
+    title: t('tools.html-wysiwyg-editor.heading4'),
     action: () => editor.value.chain().focus().toggleHeading({ level: 4 }).run(),
     isActive: () => editor.value.isActive('heading', { level: 4 }),
   },
@@ -100,21 +101,21 @@ const items: MenuItem[] = [
   {
     type: 'button',
     icon: List,
-    title: 'Bullet list',
+    title: t('tools.html-wysiwyg-editor.bulletList'),
     action: () => editor.value.chain().focus().toggleBulletList().run(),
     isActive: () => editor.value.isActive('bulletList'),
   },
   {
     type: 'button',
     icon: ListNumbers,
-    title: 'Ordered list',
+    title: t('tools.html-wysiwyg-editor.orderedList'),
     action: () => editor.value.chain().focus().toggleOrderedList().run(),
     isActive: () => editor.value.isActive('orderedList'),
   },
   {
     type: 'button',
     icon: CodePlus,
-    title: 'Code block',
+    title: t('tools.html-wysiwyg-editor.codeBlock'),
     action: () => editor.value.chain().focus().toggleCodeBlock().run(),
     isActive: () => editor.value.isActive('codeBlock'),
   },
@@ -122,7 +123,7 @@ const items: MenuItem[] = [
   {
     type: 'button',
     icon: Blockquote,
-    title: 'Blockquote',
+    title: t('tools.html-wysiwyg-editor.blockquote'),
     action: () => editor.value.chain().focus().toggleBlockquote().run(),
     isActive: () => editor.value.isActive('blockquote'),
   },
@@ -132,26 +133,26 @@ const items: MenuItem[] = [
   {
     type: 'button',
     icon: TextWrap,
-    title: 'Hard break',
+    title: t('tools.html-wysiwyg-editor.hardBreak'),
     action: () => editor.value.chain().focus().setHardBreak().run(),
   },
   {
     type: 'button',
     icon: ClearFormatting,
-    title: 'Clear format',
+    title: t('tools.html-wysiwyg-editor.clearFormat'),
     action: () => editor.value.chain().focus().clearNodes().unsetAllMarks().run(),
   },
 
   {
     type: 'button',
     icon: ArrowBack,
-    title: 'Undo',
+    title: t('tools.html-wysiwyg-editor.undo'),
     action: () => editor.value.chain().focus().undo().run(),
   },
   {
     type: 'button',
     icon: ArrowForwardUp,
-    title: 'Redo',
+    title: t('tools.html-wysiwyg-editor.redo'),
     action: () => editor.value.chain().focus().redo().run(),
   },
 ];
diff --git a/src/tools/html-wysiwyg-editor/index.ts b/src/tools/html-wysiwyg-editor/index.ts
index 461ad235..971be977 100644
--- a/src/tools/html-wysiwyg-editor/index.ts
+++ b/src/tools/html-wysiwyg-editor/index.ts
@@ -1,10 +1,11 @@
 import { Edit } from '@vicons/tabler';
 import { defineTool } from '../tool';
+import { translate as t } from '@/plugins/i18n.plugin';
 
 export const tool = defineTool({
-  name: 'HTML WYSIWYG editor',
+  name: t('tools.html-wysiwyg-editor.title'),
   path: '/html-wysiwyg-editor',
-  description: 'Online HTML editor with feature-rich WYSIWYG editor, get the source code of the content immediately.',
+  description: t('tools.html-wysiwyg-editor.description'),
   keywords: ['html', 'wysiwyg', 'editor', 'p', 'ul', 'ol', 'converter', 'live'],
   component: () => import('./html-wysiwyg-editor.vue'),
   icon: Edit,
diff --git a/src/tools/html-wysiwyg-editor/locales/en.yml b/src/tools/html-wysiwyg-editor/locales/en.yml
index 03e5e503..f05d4cf3 100644
--- a/src/tools/html-wysiwyg-editor/locales/en.yml
+++ b/src/tools/html-wysiwyg-editor/locales/en.yml
@@ -2,3 +2,20 @@ tools:
   html-wysiwyg-editor:
     title: HTML WYSIWYG editor
     description: Online HTML editor with feature-rich WYSIWYG editor, get the source code of the content immediately.
+
+    bold: Bold
+    italic: Italic
+    strike: Strike
+    inlineCode: Inline code
+    heading1: Heading 1
+    heading2: Heading 2
+    heading3: Heading 3
+    heading4: Heading 4
+    bulletList: Bullet list
+    orderedList: Ordered list
+    codeBlock: Code block
+    blockquote: Blockquote
+    hardBreak: Hard break
+    clearFormat: Clear format
+    undo: Undo
+    redo: Redo
diff --git a/src/tools/html-wysiwyg-editor/locales/zh.yml b/src/tools/html-wysiwyg-editor/locales/zh.yml
new file mode 100644
index 00000000..d0e983d0
--- /dev/null
+++ b/src/tools/html-wysiwyg-editor/locales/zh.yml
@@ -0,0 +1,21 @@
+tools:
+  html-wysiwyg-editor:
+    title: HTML所见即所得编辑器
+    description: 在线 HTML 编辑器,具有功能丰富的所见即所得编辑器,可立即获取内容的源代码。
+
+    bold: 粗体
+    italic: 斜体
+    strike: 删除线
+    inlineCode: 行内代码
+    heading1: 标题 1
+    heading2: 标题 2
+    heading3: 标题 3
+    heading4: 标题 4
+    bulletList: 无序列表
+    orderedList: 有序列表
+    codeBlock: 代码块
+    blockquote: 引用块
+    hardBreak: 强制换行
+    clearFormat: 清除格式
+    undo: 撤销
+    redo: 重做
diff --git a/src/tools/http-status-codes/http-status-codes.constants.ts b/src/tools/http-status-codes/http-status-codes.constants.ts
index 279cd7ce..49268b05 100644
--- a/src/tools/http-status-codes/http-status-codes.constants.ts
+++ b/src/tools/http-status-codes/http-status-codes.constants.ts
@@ -1,3 +1,5 @@
+import { translate as t } from '@/plugins/i18n.plugin';
+
 export const codesByCategories: {
   category: string
   codes: {
@@ -8,423 +10,404 @@ export const codesByCategories: {
   }[]
 }[] = [
   {
-    category: '1xx informational response',
+    category: t('tools.http-status-codes.1xx'),
     codes: [
       {
         code: 100,
-        name: 'Continue',
-        description: 'Waiting for the client to emit the body of the request.',
+        name: t('tools.http-status-codes.100.name'),
+        description: t('tools.http-status-codes.100.description'),
         type: 'HTTP',
       },
       {
         code: 101,
-        name: 'Switching Protocols',
-        description: 'The server has agreed to change protocol.',
+        name: t('tools.http-status-codes.101.name'),
+        description: t('tools.http-status-codes.101.description'),
         type: 'HTTP',
       },
       {
         code: 102,
-        name: 'Processing',
-        description: 'The server is processing the request, but no response is available yet.',
+        name: t('tools.http-status-codes.102.name'),
+        description: t('tools.http-status-codes.102.description'),
         type: 'WebDav',
       },
       {
         code: 103,
-        name: 'Early Hints',
-        description: 'The server returns some response headers before final HTTP message.',
+        name: t('tools.http-status-codes.103.name'),
+        description: t('tools.http-status-codes.103.description'),
         type: 'HTTP',
       },
     ],
   },
   {
-    category: '2xx success',
+    category: t('tools.http-status-codes.2xx'),
     codes: [
       {
         code: 200,
-        name: 'OK',
-        description: 'Standard response for successful HTTP requests.',
+        name: t('tools.http-status-codes.200.name'),
+        description: t('tools.http-status-codes.200.description'),
         type: 'HTTP',
       },
       {
         code: 201,
-        name: 'Created',
-        description: 'The request has been fulfilled, resulting in the creation of a new resource.',
+        name: t('tools.http-status-codes.201.name'),
+        description: t('tools.http-status-codes.201.description'),
         type: 'HTTP',
       },
       {
         code: 202,
-        name: 'Accepted',
-        description: 'The request has been accepted for processing, but the processing has not been completed.',
+        name: t('tools.http-status-codes.202.name'),
+        description: t('tools.http-status-codes.202.description'),
         type: 'HTTP',
       },
       {
         code: 203,
-        name: 'Non-Authoritative Information',
-        description:
-          'The request is successful but the content of the original request has been modified by a transforming proxy.',
+        name: t('tools.http-status-codes.203.name'),
+        description: t('tools.http-status-codes.203.description'),
         type: 'HTTP',
       },
       {
         code: 204,
-        name: 'No Content',
-        description: 'The server successfully processed the request and is not returning any content.',
+        name: t('tools.http-status-codes.204.name'),
+        description: t('tools.http-status-codes.204.description'),
         type: 'HTTP',
       },
       {
         code: 205,
-        name: 'Reset Content',
-        description: 'The server indicates to reinitialize the document view which sent this request.',
+        name: t('tools.http-status-codes.205.name'),
+        description: t('tools.http-status-codes.205.description'),
         type: 'HTTP',
       },
       {
         code: 206,
-        name: 'Partial Content',
-        description: 'The server is delivering only part of the resource due to a range header sent by the client.',
+        name: t('tools.http-status-codes.206.name'),
+        description: t('tools.http-status-codes.206.description'),
         type: 'HTTP',
       },
       {
         code: 207,
-        name: 'Multi-Status',
-        description:
-          'The message body that follows is an XML message and can contain a number of separate response codes.',
+        name: t('tools.http-status-codes.207.name'),
+        description: t('tools.http-status-codes.207.description'),
         type: 'WebDav',
       },
       {
         code: 208,
-        name: 'Already Reported',
-        description:
-          'The members of a DAV binding have already been enumerated in a preceding part of the (multistatus) response.',
+        name: t('tools.http-status-codes.208.name'),
+        description: t('tools.http-status-codes.208.description'),
         type: 'WebDav',
       },
       {
         code: 226,
-        name: 'IM Used',
-        description:
-          'The server has fulfilled a request for the resource, and the response is a representation of the result.',
+        name: t('tools.http-status-codes.226.name'),
+        description: t('tools.http-status-codes.226.description'),
         type: 'HTTP',
       },
     ],
   },
   {
-    category: '3xx redirection',
+    category: t('tools.http-status-codes.3xx'),
     codes: [
       {
         code: 300,
-        name: 'Multiple Choices',
-        description: 'Indicates multiple options for the resource that the client may follow.',
+        name: t('tools.http-status-codes.300.name'),
+        description: t('tools.http-status-codes.300.description'),
         type: 'HTTP',
       },
       {
         code: 301,
-        name: 'Moved Permanently',
-        description: 'This and all future requests should be directed to the given URI.',
+        name: t('tools.http-status-codes.301.name'),
+        description: t('tools.http-status-codes.301.description'),
         type: 'HTTP',
       },
       {
         code: 302,
-        name: 'Found',
-        description: 'Redirect to another URL. This is an example of industry practice contradicting the standard.',
+        name: t('tools.http-status-codes.302.name'),
+        description: t('tools.http-status-codes.302.description'),
         type: 'HTTP',
       },
       {
         code: 303,
-        name: 'See Other',
-        description: 'The response to the request can be found under another URI using a GET method.',
+        name: t('tools.http-status-codes.303.name'),
+        description: t('tools.http-status-codes.303.description'),
         type: 'HTTP',
       },
       {
         code: 304,
-        name: 'Not Modified',
-        description:
-          'Indicates that the resource has not been modified since the version specified by the request headers.',
+        name: t('tools.http-status-codes.304.name'),
+        description: t('tools.http-status-codes.304.description'),
         type: 'HTTP',
       },
       {
         code: 305,
-        name: 'Use Proxy',
-        description:
-          'The requested resource is available only through a proxy, the address for which is provided in the response.',
+        name: t('tools.http-status-codes.305.name'),
+        description: t('tools.http-status-codes.305.description'),
         type: 'HTTP',
       },
       {
         code: 306,
-        name: 'Switch Proxy',
-        description: 'No longer used. Originally meant "Subsequent requests should use the specified proxy."',
+        name: t('tools.http-status-codes.306.name'),
+        description: t('tools.http-status-codes.306.description'),
         type: 'HTTP',
       },
       {
         code: 307,
-        name: 'Temporary Redirect',
-        description:
-          'In this case, the request should be repeated with another URI; however, future requests should still use the original URI.',
+        name: t('tools.http-status-codes.307.name'),
+        description: t('tools.http-status-codes.307.description'),
         type: 'HTTP',
       },
       {
         code: 308,
-        name: 'Permanent Redirect',
-        description: 'The request and all future requests should be repeated using another URI.',
+        name: t('tools.http-status-codes.308.name'),
+        description: t('tools.http-status-codes.308.description'),
         type: 'HTTP',
       },
     ],
   },
   {
-    category: '4xx client error',
+    category: t('tools.http-status-codes.4xx'),
     codes: [
       {
         code: 400,
-        name: 'Bad Request',
-        description: 'The server cannot or will not process the request due to an apparent client error.',
+        name: t('tools.http-status-codes.400.name'),
+        description: t('tools.http-status-codes.400.description'),
         type: 'HTTP',
       },
       {
         code: 401,
-        name: 'Unauthorized',
-        description:
-          'Similar to 403 Forbidden, but specifically for use when authentication is required and has failed or has not yet been provided.',
+        name: t('tools.http-status-codes.401.name'),
+        description: t('tools.http-status-codes.401.description'),
         type: 'HTTP',
       },
       {
         code: 402,
-        name: 'Payment Required',
-        description:
-          'Reserved for future use. The original intention was that this code might be used as part of some form of digital cash or micropayment scheme.',
+        name: t('tools.http-status-codes.402.name'),
+        description: t('tools.http-status-codes.402.description'),
         type: 'HTTP',
       },
       {
         code: 403,
-        name: 'Forbidden',
-        description:
-          'The request was valid, but the server is refusing action. The user might not have the necessary permissions for a resource.',
+        name: t('tools.http-status-codes.403.name'),
+        description: t('tools.http-status-codes.403.description'),
         type: 'HTTP',
       },
       {
         code: 404,
-        name: 'Not Found',
-        description: 'The requested resource could not be found but may be available in the future.',
+        name: t('tools.http-status-codes.404.name'),
+        description: t('tools.http-status-codes.404.description'),
         type: 'HTTP',
       },
       {
         code: 405,
-        name: 'Method Not Allowed',
-        description: 'A request method is not supported for the requested resource.',
+        name: t('tools.http-status-codes.405.name'),
+        description: t('tools.http-status-codes.405.description'),
         type: 'HTTP',
       },
       {
         code: 406,
-        name: 'Not Acceptable',
-        description:
-          'The requested resource is capable of generating only content not acceptable according to the Accept headers sent in the request.',
+        name: t('tools.http-status-codes.406.name'),
+        description: t('tools.http-status-codes.406.description'),
         type: 'HTTP',
       },
       {
         code: 407,
-        name: 'Proxy Authentication Required',
-        description: 'The client must first authenticate itself with the proxy.',
+        name: t('tools.http-status-codes.407.name'),
+        description: t('tools.http-status-codes.407.description'),
         type: 'HTTP',
       },
       {
         code: 408,
-        name: 'Request Timeout',
-        description: 'The server timed out waiting for the request.',
+        name: t('tools.http-status-codes.408.name'),
+        description: t('tools.http-status-codes.408.description'),
         type: 'HTTP',
       },
       {
         code: 409,
-        name: 'Conflict',
-        description:
-          'Indicates that the request could not be processed because of conflict in the request, such as an edit conflict.',
+        name: t('tools.http-status-codes.409.name'),
+        description: t('tools.http-status-codes.409.description'),
         type: 'HTTP',
       },
       {
         code: 410,
-        name: 'Gone',
-        description: 'Indicates that the resource requested is no longer available and will not be available again.',
+        name: t('tools.http-status-codes.410.name'),
+        description: t('tools.http-status-codes.410.description'),
         type: 'HTTP',
       },
       {
         code: 411,
-        name: 'Length Required',
-        description:
-          'The request did not specify the length of its content, which is required by the requested resource.',
+        name: t('tools.http-status-codes.411.name'),
+        description: t('tools.http-status-codes.411.description'),
         type: 'HTTP',
       },
       {
         code: 412,
-        name: 'Precondition Failed',
-        description: 'The server does not meet one of the preconditions that the requester put on the request.',
+        name: t('tools.http-status-codes.412.name'),
+        description: t('tools.http-status-codes.412.description'),
         type: 'HTTP',
       },
       {
         code: 413,
-        name: 'Payload Too Large',
-        description: 'The request is larger than the server is willing or able to process.',
+        name: t('tools.http-status-codes.413.name'),
+        description: t('tools.http-status-codes.413.description'),
         type: 'HTTP',
       },
       {
         code: 414,
-        name: 'URI Too Long',
-        description: 'The URI provided was too long for the server to process.',
+        name: t('tools.http-status-codes.414.name'),
+        description: t('tools.http-status-codes.414.description'),
         type: 'HTTP',
       },
       {
         code: 415,
-        name: 'Unsupported Media Type',
-        description: 'The request entity has a media type which the server or resource does not support.',
+        name: t('tools.http-status-codes.415.name'),
+        description: t('tools.http-status-codes.415.description'),
         type: 'HTTP',
       },
       {
         code: 416,
-        name: 'Range Not Satisfiable',
-        description: 'The client has asked for a portion of the file, but the server cannot supply that portion.',
+        name: t('tools.http-status-codes.416.name'),
+        description: t('tools.http-status-codes.416.description'),
         type: 'HTTP',
       },
       {
         code: 417,
-        name: 'Expectation Failed',
-        description: 'The server cannot meet the requirements of the Expect request-header field.',
+        name: t('tools.http-status-codes.417.name'),
+        description: t('tools.http-status-codes.417.description'),
         type: 'HTTP',
       },
       {
         code: 418,
-        name: 'I\'m a teapot',
-        description: 'The server refuses the attempt to brew coffee with a teapot.',
+        name: t('tools.http-status-codes.418.name'),
+        description: t('tools.http-status-codes.418.description'),
         type: 'HTTP',
       },
       {
         code: 421,
-        name: 'Misdirected Request',
-        description: 'The request was directed at a server that is not able to produce a response.',
+        name: t('tools.http-status-codes.421.name'),
+        description: t('tools.http-status-codes.421.description'),
         type: 'HTTP',
       },
       {
         code: 422,
-        name: 'Unprocessable Entity',
-        description: 'The request was well-formed but was unable to be followed due to semantic errors.',
+        name: t('tools.http-status-codes.422.name'),
+        description: t('tools.http-status-codes.422.description'),
         type: 'HTTP',
       },
       {
         code: 423,
-        name: 'Locked',
-        description: 'The resource that is being accessed is locked.',
+        name: t('tools.http-status-codes.423.name'),
+        description: t('tools.http-status-codes.423.description'),
         type: 'HTTP',
       },
       {
         code: 424,
-        name: 'Failed Dependency',
-        description: 'The request failed due to failure of a previous request.',
+        name: t('tools.http-status-codes.424.name'),
+        description: t('tools.http-status-codes.424.description'),
         type: 'HTTP',
       },
       {
         code: 425,
-        name: 'Too Early',
-        description: 'Indicates that the server is unwilling to risk processing a request that might be replayed.',
+        name: t('tools.http-status-codes.425.name'),
+        description: t('tools.http-status-codes.425.description'),
         type: 'HTTP',
       },
       {
         code: 426,
-        name: 'Upgrade Required',
-        description: 'The client should switch to a different protocol such as TLS/1.0.',
+        name: t('tools.http-status-codes.426.name'),
+        description: t('tools.http-status-codes.426.description'),
         type: 'HTTP',
       },
       {
         code: 428,
-        name: 'Precondition Required',
-        description: 'The origin server requires the request to be conditional.',
+        name: t('tools.http-status-codes.428.name'),
+        description: t('tools.http-status-codes.428.description'),
         type: 'HTTP',
       },
       {
         code: 429,
-        name: 'Too Many Requests',
-        description: 'The user has sent too many requests in a given amount of time.',
+        name: t('tools.http-status-codes.429.name'),
+        description: t('tools.http-status-codes.429.description'),
         type: 'HTTP',
       },
       {
         code: 431,
-        name: 'Request Header Fields Too Large',
-        description:
-          'The server is unwilling to process the request because either an individual header field, or all the header fields collectively, are too large.',
+        name: t('tools.http-status-codes.431.name'),
+        description: t('tools.http-status-codes.431.description'),
         type: 'HTTP',
       },
       {
         code: 451,
-        name: 'Unavailable For Legal Reasons',
-        description:
-          'A server operator has received a legal demand to deny access to a resource or to a set of resources that includes the requested resource.',
+        name: t('tools.http-status-codes.451.name'),
+        description: t('tools.http-status-codes.451.description'),
         type: 'HTTP',
       },
     ],
   },
   {
-    category: '5xx server error',
+    category: t('tools.http-status-codes.5xx'),
     codes: [
       {
         code: 500,
-        name: 'Internal Server Error',
-        description:
-          'A generic error message, given when an unexpected condition was encountered and no more specific message is suitable.',
+        name: t('tools.http-status-codes.500.name'),
+        description: t('tools.http-status-codes.500.description'),
         type: 'HTTP',
       },
       {
         code: 501,
-        name: 'Not Implemented',
-        description:
-          'The server either does not recognize the request method, or it lacks the ability to fulfill the request.',
+        name: t('tools.http-status-codes.501.name'),
+        description: t('tools.http-status-codes.501.description'),
         type: 'HTTP',
       },
       {
         code: 502,
-        name: 'Bad Gateway',
-        description:
-          'The server was acting as a gateway or proxy and received an invalid response from the upstream server.',
+        name: t('tools.http-status-codes.502.name'),
+        description: t('tools.http-status-codes.502.description'),
         type: 'HTTP',
       },
       {
         code: 503,
-        name: 'Service Unavailable',
-        description: 'The server is currently unavailable (because it is overloaded or down for maintenance).',
+        name: t('tools.http-status-codes.503.name'),
+        description: t('tools.http-status-codes.503.description'),
         type: 'HTTP',
       },
       {
         code: 504,
-        name: 'Gateway Timeout',
-        description:
-          'The server was acting as a gateway or proxy and did not receive a timely response from the upstream server.',
+        name: t('tools.http-status-codes.504.name'),
+        description: t('tools.http-status-codes.504.description'),
         type: 'HTTP',
       },
       {
         code: 505,
-        name: 'HTTP Version Not Supported',
-        description: 'The server does not support the HTTP protocol version used in the request.',
+        name: t('tools.http-status-codes.505.name'),
+        description: t('tools.http-status-codes.505.description'),
         type: 'HTTP',
       },
       {
         code: 506,
-        name: 'Variant Also Negotiates',
-        description: 'Transparent content negotiation for the request results in a circular reference.',
+        name: t('tools.http-status-codes.506.name'),
+        description: t('tools.http-status-codes.506.description'),
         type: 'HTTP',
       },
       {
         code: 507,
-        name: 'Insufficient Storage',
-        description: 'The server is unable to store the representation needed to complete the request.',
+        name: t('tools.http-status-codes.507.name'),
+        description: t('tools.http-status-codes.507.description'),
         type: 'HTTP',
       },
       {
         code: 508,
-        name: 'Loop Detected',
-        description: 'The server detected an infinite loop while processing the request.',
+        name: t('tools.http-status-codes.508.name'),
+        description: t('tools.http-status-codes.508.description'),
         type: 'HTTP',
       },
       {
         code: 510,
-        name: 'Not Extended',
-        description: 'Further extensions to the request are required for the server to fulfill it.',
+        name: t('tools.http-status-codes.510.name'),
+        description: t('tools.http-status-codes.510.description'),
         type: 'HTTP',
       },
       {
         code: 511,
-        name: 'Network Authentication Required',
-        description: 'The client needs to authenticate to gain network access.',
+        name: t('tools.http-status-codes.511.name'),
+        description: t('tools.http-status-codes.511.description'),
         type: 'HTTP',
       },
     ],
diff --git a/src/tools/http-status-codes/http-status-codes.vue b/src/tools/http-status-codes/http-status-codes.vue
index 84ab3137..434ae673 100644
--- a/src/tools/http-status-codes/http-status-codes.vue
+++ b/src/tools/http-status-codes/http-status-codes.vue
@@ -1,8 +1,10 @@
 
 
@@ -25,7 +27,7 @@ const codesByCategoryFiltered = computed(() => {
   
     
 
diff --git a/src/tools/http-status-codes/index.ts b/src/tools/http-status-codes/index.ts
index 43afae83..9ba257fd 100644
--- a/src/tools/http-status-codes/index.ts
+++ b/src/tools/http-status-codes/index.ts
@@ -1,17 +1,18 @@
 import { HttpRound } from '@vicons/material';
 import { defineTool } from '../tool';
 
-import { codesByCategories } from './http-status-codes.constants';
+// import { codesByCategories } from './http-status-codes.constants';
+import { translate as t } from '@/plugins/i18n.plugin';
 
 export const tool = defineTool({
-  name: 'HTTP status codes',
+  name: t('tools.http-status-codes.title'),
   path: '/http-status-codes',
-  description: 'The list of all HTTP status codes their name and their meaning.',
+  description: t('tools.http-status-codes.description'),
   keywords: [
     'http',
     'status',
     'codes',
-    ...codesByCategories.flatMap(({ codes }) => codes.flatMap(({ code, name }) => [String(code), name])),
+    // ...codesByCategories.flatMap(({ codes }) => codes.flatMap(({ code, name }) => [String(code), name])),
   ],
   component: () => import('./http-status-codes.vue'),
   icon: HttpRound,
diff --git a/src/tools/http-status-codes/locales/en.yml b/src/tools/http-status-codes/locales/en.yml
index 07f2a168..e2a02caa 100644
--- a/src/tools/http-status-codes/locales/en.yml
+++ b/src/tools/http-status-codes/locales/en.yml
@@ -2,3 +2,201 @@ tools:
   http-status-codes:
     title: HTTP status codes
     description: The list of all HTTP status codes their name and their meaning.
+
+    searchPlaceholder: Search http status...
+    searchResults: Search results
+
+    1xx: 1xx informational response
+    100:
+      name: Continue
+      description: Waiting for the client to emit the body of the request.
+    101:
+      name: Switching Protocols
+      description: The server has agreed to change protocol.
+    102:
+      name: Processing
+      description: The server is processing the request, but no response is available yet.
+    103:
+      name: Early Hints
+      description: The server returns some response headers before final HTTP message.
+    2xx: 2xx success
+    200:
+      name: OK
+      description: Standard response for successful HTTP requests.
+    201:
+      name: Created
+      description: The request has been fulfilled, resulting in the creation of a new resource.
+    202:
+      name: Accepted
+      description: The request has been accepted for processing, but the processing has not been completed.
+    203:
+      name: Non-Authoritative Information
+      description: The request is successful but the content of the original request has been modified by a transforming proxy.
+    204:
+      name: No Content
+      description: The server successfully processed the request and is not returning any content.
+    205:
+      name: Reset Content
+      description: The server indicates to reinitialize the document view which sent this request.
+    206:
+      name: Partial Content
+      description: The server is delivering only part of the resource due to a range header sent by the client.
+    207:
+      name: Multi-Status
+      description: The message body that follows is an XML message and can contain a number of separate response codes.
+    208:
+      name: Already Reported
+      description: The members of a DAV binding have already been enumerated in a preceding part of the (multistatus) response.
+    226:
+      name: IM Used
+      description: The server has fulfilled a request for the resource, and the response is a representation of the result.
+    3xx: 3xx redirection
+    300:
+      name: Multiple Choices
+      description: Indicates multiple options for the resource that the client may follow.
+    301:
+      name: Moved Permanently
+      description: This and all future requests should be directed to the given URI.
+    302:
+      name: Found
+      description: Redirect to another URL. This is an example of industry practice contradicting the standard.
+    303:
+      name: See Other
+      description: The response to the request can be found under another URI using a GET method.
+    304:
+      name: Not Modified
+      description: Indicates that the resource has not been modified since the version specified by the request headers.
+    305:
+      name: Use Proxy
+      description: The requested resource is available only through a proxy, the address for which is provided in the response.
+    306:
+      name: Switch Proxy
+      description: No longer used. Originally meant "Subsequent requests should use the specified proxy."
+    307:
+      name: Temporary Redirect
+      description: In this case, the request should be repeated with another URI; however, future requests should still use the original URI.
+    308:
+      name: Permanent Redirect
+      description: The request and all future requests should be repeated using another URI.
+    4xx: 4xx client error
+    400:
+      name: Bad Request
+      description: The server cannot or will not process the request due to an apparent client error.
+    401:
+      name: Unauthorized
+      description: Similar to 403 Forbidden, but specifically for use when authentication is required and has failed or has not yet been provided.
+    402:
+      name: Payment Required
+      description: Reserved for future use. The original intention was that this code might be used as part of some form of digital cash or micropayment scheme.
+    403:
+      name: Forbidden
+      description: The request was valid, but the server is refusing action. The user might not have the necessary permissions for a resource.
+    404:
+      name: Not Found
+      description: The requested resource could not be found but may be available in the future.
+    405:
+      name: Method Not Allowed
+      description: A request method is not supported for the requested resource.
+    406:
+      name: Not Acceptable
+      description: The requested resource is capable of generating only content not acceptable according to the Accept headers sent in the request.
+    407:
+      name: Proxy Authentication Required
+      description: The client must first authenticate itself with the proxy.
+    408:
+      name: Request Timeout
+      description: The server timed out waiting for the request.
+    409:
+      name: Conflict
+      description: Indicates that the request could not be processed because of conflict in the request, such as an edit conflict.
+    410:
+      name: Gone
+      description: Indicates that the resource requested is no longer available and will not be available again.
+    411:
+      name: Length Required
+      description: The request did not specify the length of its content, which is required by the requested resource.
+    412:
+      name: Precondition Failed
+      description: The server does not meet one of the preconditions that the requester put on the request.
+    413:
+      name: Payload Too Large
+      description: The request is larger than the server is willing or able to process.
+    414:
+      name: URI Too Long
+      description: The URI provided was too long for the server to process.
+    415:
+      name: Unsupported Media Type
+      description: The request entity has a media type which the server or resource does not support.
+    416:
+      name: Range Not Satisfiable
+      description: The client has asked for a portion of the file, but the server cannot supply that portion.
+    417:
+      name: Expectation Failed
+      description: The server cannot meet the requirements of the Expect request-header field.
+    418:
+      name: I'm a teapot
+      description: The server refuses the attempt to brew coffee with a teapot.
+    421:
+      name: Misdirected Request
+      description: The request was directed at a server that is not able to produce a response.
+    422:
+      name: Unprocessable Entity
+      description: The request was well-formed but was unable to be followed due to semantic errors.
+    423:
+      name: Locked
+      description: The resource that is being accessed is locked.
+    424:
+      name: Failed Dependency
+      description: The request failed due to failure of a previous request.
+    425:
+      name: Too Early
+      description: Indicates that the server is unwilling to risk processing a request that might be replayed.
+    426:
+      name: Upgrade Required
+      description: The client should switch to a different protocol such as TLS/1.0.
+    428:
+      name: Precondition Required
+      description: The origin server requires the request to be conditional.
+    429:
+      name: Too Many Requests
+      description: The user has sent too many requests in a given amount of time.
+    431:
+      name: Request Header Fields Too Large
+      description: The server is unwilling to process the request because either an individual header field, or all the header fields collectively, are too large.
+    451:
+      name: Unavailable For Legal Reasons
+      description: A server operator has received a legal demand to deny access to a resource or to a set of resources that includes the requested resource.
+    5xx: 5xx server error
+    500:
+      name: Internal Server Error
+      description: A generic error message, given when an unexpected condition was encountered and no more specific message is suitable.
+    501:
+      name: Not Implemented
+      description: The server either does not recognize the request method, or it lacks the ability to fulfill the request.
+    502:
+      name: Bad Gateway
+      description: The server was acting as a gateway or proxy and received an invalid response from the upstream server.
+    503:
+      name: Service Unavailable
+      description: The server is currently unavailable (because it is overloaded or down for maintenance).
+    504:
+      name: Gateway Timeout
+      description: The server was acting as a gateway or proxy and did not receive a timely response from the upstream server.
+    505:
+      name: HTTP Version Not Supported
+      description: The server does not support the HTTP protocol version used in the request.
+    506:
+      name: Variant Also Negotiates
+      description: Transparent content negotiation for the request results in a circular reference.
+    507:
+      name: Insufficient Storage
+      description: The server is unable to store the representation needed to complete the request.
+    508:
+      name: Loop Detected
+      description: The server detected an infinite loop while processing the request.
+    510:
+      name: Not Extended
+      description: Further extensions to the request are required for the server to fulfill it.
+    511:
+      name: Network Authentication Required
+      description: The client needs to authenticate to gain network access.
diff --git a/src/tools/http-status-codes/locales/zh.yml b/src/tools/http-status-codes/locales/zh.yml
new file mode 100644
index 00000000..1fc3def2
--- /dev/null
+++ b/src/tools/http-status-codes/locales/zh.yml
@@ -0,0 +1,202 @@
+tools:
+  http-status-codes:
+    title: HTTP 状态码
+    description: 所有 HTTP 状态码及其名称和含义的列表。
+
+    searchPlaceholder: 搜索 HTTP 状态码...
+    searchResults: 搜索结果
+
+    1xx: 1xx 信息性响应
+    100:
+      name: 继续
+      description: 等待客户端发送请求主体。
+    101:
+      name: 切换协议
+      description: 服务器已同意切换协议。
+    102:
+      name: 处理中
+      description: 服务器正在处理请求,但尚未有响应可用。
+    103:
+      name: 早期提示
+      description: 服务器在最终 HTTP 消息之前返回一些响应头。
+    2xx: 2xx 成功
+    200:
+      name: OK
+      description: 成功的标准 HTTP 请求响应。
+    201:
+      name: 已创建
+      description: 请求已成功,导致创建新资源。
+    202:
+      name: 已接受
+      description: 请求已被接受处理,但处理尚未完成。
+    203:
+      name: 非权威信息
+      description: 请求成功,但原始请求的内容已被转换代理修改。
+    204:
+      name: 无内容
+      description: 服务器成功处理请求,但未返回任何内容。
+    205:
+      name: 重置内容
+      description: 服务器指示重新初始化发送此请求的文档视图。
+    206:
+      name: 部分内容
+      description: 服务器仅因客户端发送的范围头而传送资源的部分。
+    207:
+      name: 多状态
+      description: 接下来的消息主体是 XML 消息,可以包含许多独立的响应代码。
+    208:
+      name: 已报告
+      description: DAV 绑定的成员已在响应的前一部分中枚举。
+    226:
+      name: 使用 IM
+      description: 服务器已满足对资源的请求,响应是结果的表示。
+    3xx: 3xx 重定向
+    300:
+      name: 多种选择
+      description: 表示客户端可以跟随的资源的多个选项。
+    301:
+      name: 永久移动
+      description: 此次及所有后续请求应重定向到给定的 URI。
+    302:
+      name: 找到
+      description: 重定向到另一个 URL。这是一个违反标准的行业实践示例。
+    303:
+      name: 查看其他
+      description: 请求的响应可以在另一个 URI 下使用 GET 方法找到。
+    304:
+      name: 未修改
+      description: 表示资源自请求标头指定的版本以来未被修改。
+    305:
+      name: 使用代理
+      description: 请求的资源仅通过代理提供,响应中提供了代理的地址。
+    306:
+      name: 切换代理
+      description: 不再使用。最初的含义是“后续请求应使用指定的代理”。
+    307:
+      name: 临时重定向
+      description: 在这种情况下,应重复使用另一个 URI 进行请求;但是,将来的请求仍应使用原始 URI。
+    308:
+      name: 永久重定向
+      description: 请求和所有后续请求应重复使用另一个 URI。
+    4xx: 4xx 客户端错误
+    400:
+      name: 错误请求
+      description: 由于明显的客户端错误,服务器无法处理请求或不会处理请求。
+    401:
+      name: 未经授权
+      description: 类似于 403 Forbidden,但专门用于在需要验证但验证失败或尚未提供的情况下使用。
+    402:
+      name: 需要付款
+      description: 保留以备将来使用。最初的意图是,该代码可能作为某种数字货币或微支付方案的一部分使用。
+    403:
+      name: 禁止
+      description: 请求有效,但服务器拒绝执行操作。用户可能没有资源所需的必要权限。
+    404:
+      name: 未找到
+      description: 请求的资源未找到,但将来可能会可用。
+    405:
+      name: 方法不允许
+      description: 请求方法不受请求资源支持。
+    406:
+      name: 不可接受
+      description: 请求的资源能够生成的内容不符合请求中发送的 Accept 标头。
+    407:
+      name: 需要代理身份验证
+      description: 客户端必须首先通过代理进行身份验证。
+    408:
+      name: 请求超时
+      description: 服务器在等待请求时超时。
+    409:
+      name: 冲突
+      description: 表示由于请求中的冲突(如编辑冲突)无法处理请求。
+    410:
+      name: 已消失
+      description: 表示请求的资源不再可用,也不会再次可用。
+    411:
+      name: 需要长度
+      description: 请求未指定所需资源的长度。
+    412:
+      name: 前提条件失败
+      description: 服务器未满足请求者对请求的其中一个前提条件。
+    413:
+      name: 负载过大
+      description: 请求的大小超过服务器愿意或能够处理的范围。
+    414:
+      name: URI 过长
+      description: 提供的 URI 对服务器来说太长,无法处理。
+    415:
+      name: 不支持的媒体类型
+      description: 请求实体具有服务器或资源不支持的媒体类型。
+    416:
+      name: 范围不可满足
+      description: 客户端请求文件的一部分,但服务器无法提供该部分。
+    417:
+      name: 预期失败
+      description: 服务器无法满足 Expect 请求标头字段的要求。
+    418:
+      name: 我是茶壶
+      description: 服务器拒绝使用茶壶煮咖啡。
+    421:
+      name: 请求错误
+      description: 请求指向无法生成响应的服务器。
+    422:
+      name: 无法处理的实体
+      description: 请求格式正确,但由于语义错误无法进行后续处理。
+    423:
+      name: 已锁定
+      description: 正在访问的资源已被锁定。
+    424:
+      name: 失败的依赖
+      description: 由于先前请求的失败,请求失败。
+    425:
+      name: 太早
+      description: 表示服务器不愿冒险处理可能会被重播的请求。
+    426:
+      name: 需要升级
+      description: 客户端应切换到其他协议,如 TLS/1.0。
+    428:
+      name: 需要前提条件
+      description: 源服务器要求请求是有条件的。
+    429:
+      name: 请求过多
+      description: 用户在一定时间内发送了太多请求。
+    431:
+      name: 请求头字段太大
+      description: 服务器不愿处理请求,因为单个标头字段或所有标头字段的总和太大。
+    451:
+      name: 因法律原因不可用
+      description: 服务器操作员收到法律要求拒绝访问资源或包含请求的资源集。
+    5xx: 5xx 服务器错误
+    500:
+      name: 内部服务器错误
+      description: 遇到意外情况并且没有更具体消息适用时给出的通用错误消息。
+    501:
+      name: 未实现
+      description: 服务器不识别请求方法,或缺乏实现请求的能力。
+    502:
+      name: 错误网关
+      description: 服务器作为网关或代理行事,并从上游服务器接收到无效响应。
+    503:
+      name: 服务不可用
+      description: 服务器当前不可用(因为过载或正在维护)。
+    504:
+      name: 网关超时
+      description: 服务器作为网关或代理行事,未从上游服务器收到及时响应。
+    505:
+      name: 不支持的 HTTP 版本
+      description: 服务器不支持请求中使用的 HTTP 协议版本。
+    506:
+      name: 变体也进行协商
+      description: 用于请求结果的透明内容协商导致循环引用。
+    507:
+      name: 存储空间不足
+      description: 服务器无法存储完成请求所需的表示。
+    508:
+      name: 检测到循环
+      description: 服务器在处理请求时检测到无限循环。
+    510:
+      name: 未扩展
+      description: 服务器需要进一步扩展请求才能满足它。
+    511:
+      name: 需要网络认证
+      description: 客户端需要进行身份验证以获得网络访问权限。
diff --git a/src/tools/json-diff/diff-viewer/diff-viewer.vue b/src/tools/json-diff/diff-viewer/diff-viewer.vue
index 1c585df7..7070ab17 100644
--- a/src/tools/json-diff/diff-viewer/diff-viewer.vue
+++ b/src/tools/json-diff/diff-viewer/diff-viewer.vue
@@ -5,6 +5,8 @@ import { DiffRootViewer } from './diff-viewer.models';
 import { useAppTheme } from '@/ui/theme/themes';
 
 const props = defineProps<{ leftJson: unknown; rightJson: unknown }>();
+
+const { t } = useI18n();
 const onlyShowDifferences = ref(false);
 const { leftJson, rightJson } = toRefs(props);
 const appTheme = useAppTheme();
@@ -20,14 +22,14 @@ const showResults = computed(() => !_.isUndefined(leftJson.value) && !_.isUndefi
 
   
     
-      
+      
         
       
     
 
     
       
-        The provided JSONs are the same
+        {{ t('tools.json-diff.jsonAreTheSame') }}
       
       
     
diff --git a/src/tools/json-diff/index.ts b/src/tools/json-diff/index.ts
index 7c4c1eee..7f21808d 100644
--- a/src/tools/json-diff/index.ts
+++ b/src/tools/json-diff/index.ts
@@ -1,10 +1,11 @@
 import { CompareArrowsRound } from '@vicons/material';
 import { defineTool } from '../tool';
+import { translate as t } from '@/plugins/i18n.plugin';
 
 export const tool = defineTool({
-  name: 'JSON diff',
+  name: t('tools.json-diff.title'),
   path: '/json-diff',
-  description: 'Compare two JSON objects and get the differences between them.',
+  description: t('tools.json-diff.description'),
   keywords: ['json', 'diff', 'compare', 'difference', 'object', 'data'],
   component: () => import('./json-diff.vue'),
   icon: CompareArrowsRound,
diff --git a/src/tools/json-diff/json-diff.vue b/src/tools/json-diff/json-diff.vue
index 80ada78b..2fceb713 100644
--- a/src/tools/json-diff/json-diff.vue
+++ b/src/tools/json-diff/json-diff.vue
@@ -5,6 +5,8 @@ import DiffsViewer from './diff-viewer/diff-viewer.vue';
 import { withDefaultOnError } from '@/utils/defaults';
 import { isNotThrowing } from '@/utils/boolean';
 
+const { t } = useI18n();
+
 const rawLeftJson = ref('');
 const rawRightJson = ref('');
 
@@ -14,7 +16,7 @@ const rightJson = computed(() => withDefaultOnError(() => JSON5.parse(rawRightJs
 const jsonValidationRules = [
   {
     validator: (value: string) => value === '' || isNotThrowing(() => JSON5.parse(value)),
-    message: 'Invalid JSON format',
+    message: t('tools.json-diff.invalidJSONFormat'),
   },
 ];
 
@@ -23,8 +25,8 @@ const jsonValidationRules = [
   
 = {
-  typ: 'Type',
-  alg: 'Algorithm',
-  iss: 'Issuer',
-  sub: 'Subject',
-  aud: 'Audience',
-  exp: 'Expiration Time',
-  nbf: 'Not Before',
-  iat: 'Issued At',
-  jti: 'JWT ID',
-  name: 'Full name',
-  given_name: 'Given name(s) or first name(s)',
-  family_name: 'Surname(s) or last name(s)',
-  middle_name: 'Middle name(s)',
-  nickname: 'Casual name',
-  preferred_username: 'Shorthand name by which the End-User wishes to be referred to',
-  profile: 'Profile page URL',
-  picture: 'Profile picture URL',
-  website: 'Web page or blog URL',
-  email: 'Preferred e-mail address',
-  email_verified: 'True if the e-mail address has been verified; otherwise false',
-  gender: 'Gender',
-  birthdate: 'Birthday',
-  zoneinfo: 'Time zone',
-  locale: 'Locale',
-  phone_number: 'Preferred telephone number',
-  phone_number_verified: 'True if the phone number has been verified; otherwise false',
-  address: 'Preferred postal address',
-  updated_at: 'Time the information was last updated',
-  azp: 'Authorized party - the party to which the ID Token was issued',
-  nonce: 'Value used to associate a Client session with an ID Token',
-  auth_time: 'Time when the authentication occurred',
-  at_hash: 'Access Token hash value',
-  c_hash: 'Code hash value',
-  acr: 'Authentication Context Class Reference',
-  amr: 'Authentication Methods References',
-  sub_jwk: 'Public key used to check the signature of an ID Token',
-  cnf: 'Confirmation',
-  sip_from_tag: 'SIP From tag header field parameter value',
-  sip_date: 'SIP Date header field value',
-  sip_callid: 'SIP Call-Id header field value',
-  sip_cseq_num: 'SIP CSeq numeric header field parameter value',
-  sip_via_branch: 'SIP Via branch header field parameter value',
-  orig: 'Originating Identity String',
-  dest: 'Destination Identity String',
-  mky: 'Media Key Fingerprint String',
-  events: 'Security Events',
-  toe: 'Time of Event',
-  txn: 'Transaction Identifier',
-  rph: 'Resource Priority Header Authorization',
-  sid: 'Session ID',
-  vot: 'Vector of Trust value',
-  vtm: 'Vector of Trust trustmark URL',
-  attest: 'Attestation level as defined in SHAKEN framework',
-  origid: 'Originating Identifier as defined in SHAKEN framework',
-  act: 'Actor',
-  scope: 'Scope Values',
-  client_id: 'Client Identifier',
-  may_act: 'Authorized Actor - the party that is authorized to become the actor',
-  jcard: 'jCard data',
-  at_use_nbr: 'Number of API requests for which the access token can be used',
-  div: 'Diverted Target of a Call',
-  opt: 'Original PASSporT (in Full Form)',
-  vc: 'Verifiable Credential as specified in the W3C Recommendation',
-  vp: 'Verifiable Presentation as specified in the W3C Recommendation',
-  sph: 'SIP Priority header field',
-  ace_profile: 'ACE profile a token is supposed to be used with.',
-  cnonce: 'Client nonce',
-  exi: 'Expires in',
-  roles: 'Roles',
-  groups: 'Groups',
-  entitlements: 'Entitlements',
-  token_introspection: 'Token introspection response',
+  typ: t('tools.jwt-parser.typ'),
+  alg: t('tools.jwt-parser.alg'),
+  iss: t('tools.jwt-parser.iss'),
+  sub: t('tools.jwt-parser.sub'),
+  aud: t('tools.jwt-parser.aud'),
+  exp: t('tools.jwt-parser.exp'),
+  nbf: t('tools.jwt-parser.nbf'),
+  iat: t('tools.jwt-parser.iat'),
+  jti: t('tools.jwt-parser.jti'),
+  name: t('tools.jwt-parser.name'),
+  given_name: t('tools.jwt-parser.givenName'),
+  family_name: t('tools.jwt-parser.familyName'),
+  middle_name: t('tools.jwt-parser.middleName'),
+  nickname: t('tools.jwt-parser.nickname'),
+  preferred_username: t('tools.jwt-parser.preferredUsername'),
+  profile: t('tools.jwt-parser.profile'),
+  picture: t('tools.jwt-parser.picture'),
+  website: t('tools.jwt-parser.website'),
+  email: t('tools.jwt-parser.email'),
+  email_verified: t('tools.jwt-parser.emailVerified'),
+  gender: t('tools.jwt-parser.gender'),
+  birthdate: t('tools.jwt-parser.birthdate'),
+  zoneinfo: t('tools.jwt-parser.zoneinfo'),
+  locale: t('tools.jwt-parser.locale'),
+  phone_number: t('tools.jwt-parser.phoneNumber'),
+  phone_number_verified: t('tools.jwt-parser.phoneNumberVerified'),
+  address: t('tools.jwt-parser.address'),
+  updated_at: t('tools.jwt-parser.updatedAt'),
+  azp: t('tools.jwt-parser.azp'),
+  nonce: t('tools.jwt-parser.nonce'),
+  auth_time: t('tools.jwt-parser.authTime'),
+  at_hash: t('tools.jwt-parser.atHash'),
+  c_hash: t('tools.jwt-parser.cHash'),
+  acr: t('tools.jwt-parser.acr'),
+  amr: t('tools.jwt-parser.amr'),
+  sub_jwk: t('tools.jwt-parser.subJwk'),
+  cnf: t('tools.jwt-parser.cnf'),
+  sip_from_tag: t('tools.jwt-parser.sipFromTag'),
+  sip_date: t('tools.jwt-parser.sipDate'),
+  sip_callid: t('tools.jwt-parser.sipCallid'),
+  sip_cseq_num: t('tools.jwt-parser.sipCseqNum'),
+  sip_via_branch: t('tools.jwt-parser.sipViaBranch'),
+  orig: t('tools.jwt-parser.orig'),
+  dest: t('tools.jwt-parser.dest'),
+  mky: t('tools.jwt-parser.mky'),
+  events: t('tools.jwt-parser.events'),
+  toe: t('tools.jwt-parser.toe'),
+  txn: t('tools.jwt-parser.txn'),
+  rph: t('tools.jwt-parser.rph'),
+  sid: t('tools.jwt-parser.sid'),
+  vot: t('tools.jwt-parser.vot'),
+  vtm: t('tools.jwt-parser.vtm'),
+  attest: t('tools.jwt-parser.attest'),
+  origid: t('tools.jwt-parser.origid'),
+  act: t('tools.jwt-parser.act'),
+  scope: t('tools.jwt-parser.scope'),
+  client_id: t('tools.jwt-parser.clientId'),
+  may_act: t('tools.jwt-parser.mayAct'),
+  jcard: t('tools.jwt-parser.jcard'),
+  at_use_nbr: t('tools.jwt-parser.atUseNbr'),
+  div: t('tools.jwt-parser.div'),
+  opt: t('tools.jwt-parser.opt'),
+  vc: t('tools.jwt-parser.vc'),
+  vp: t('tools.jwt-parser.vp'),
+  sph: t('tools.jwt-parser.sph'),
+  ace_profile: t('tools.jwt-parser.aceProfile'),
+  cnonce: t('tools.jwt-parser.cnonce'),
+  exi: t('tools.jwt-parser.exi'),
+  roles: t('tools.jwt-parser.roles'),
+  groups: t('tools.jwt-parser.groups'),
+  entitlements: t('tools.jwt-parser.entitlements'),
+  token_introspection: t('tools.jwt-parser.tokenIntrospection'),
 };
diff --git a/src/tools/jwt-parser/jwt-parser.vue b/src/tools/jwt-parser/jwt-parser.vue
index 6b30fc0c..791ec571 100644
--- a/src/tools/jwt-parser/jwt-parser.vue
+++ b/src/tools/jwt-parser/jwt-parser.vue
@@ -4,6 +4,8 @@ import { useValidation } from '@/composable/validation';
 import { isNotThrowing } from '@/utils/boolean';
 import { withDefaultOnError } from '@/utils/defaults';
 
+const { t } = useI18n();
+
 const rawJwt = ref(
   'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c',
 );
@@ -13,8 +15,8 @@ const decodedJWT = computed(() =>
 );
 
 const sections = [
-  { key: 'header', title: 'Header' },
-  { key: 'payload', title: 'Payload' },
+  { key: 'header', title: t('tools.jwt-parser.header') },
+  { key: 'payload', title: t('tools.jwt-parser.payload') },
 ] as const;
 
 const validation = useValidation({
@@ -22,7 +24,7 @@ const validation = useValidation({
   rules: [
     {
       validator: value => value.length > 0 && isNotThrowing(() => decodeJwt({ jwt: rawJwt.value })),
-      message: 'Invalid JWT',
+      message: t('tools.jwt-parser.invalidJWT'),
     },
   ],
 });
@@ -30,7 +32,7 @@ const validation = useValidation({
 
 
   
-    
+    
 
     
       
diff --git a/src/tools/jwt-parser/locales/en.yml b/src/tools/jwt-parser/locales/en.yml
index 956f9239..ef3cb2d4 100644
--- a/src/tools/jwt-parser/locales/en.yml
+++ b/src/tools/jwt-parser/locales/en.yml
@@ -2,3 +2,97 @@ tools:
   jwt-parser:
     title: JWT parser
     description: Parse and decode your JSON Web Token (jwt) and display its content.
+
+    label: JWT to decode
+    placeholder: Put your token here...
+    header: Header
+    payload: Payload
+
+    invalidJWT: Invalid JWT
+
+    HS256: 'HMAC using SHA-256'
+    HS384: 'HMAC using SHA-384'
+    HS512: 'HMAC using SHA-512'
+    RS256: 'RSASSA-PKCS1-v1_5 using SHA-256'
+    RS384: 'RSASSA-PKCS1-v1_5 using SHA-384'
+    RS512: 'RSASSA-PKCS1-v1_5 using SHA-512'
+    ES256: 'ECDSA using P-256 and SHA-256'
+    ES384: 'ECDSA using P-384 and SHA-384'
+    ES512: 'ECDSA using P-521 and SHA-512'
+    PS256: 'RSASSA-PSS using SHA-256 and MGF1 with SHA-256'
+    PS384: 'RSASSA-PSS using SHA-384 and MGF1 with SHA-384'
+    PS512: 'RSASSA-PSS using SHA-512 and MGF1 with SHA-512'
+    none: 'No digital signature or MAC performed'
+
+    typ: 'Type'
+    alg: 'Algorithm'
+    iss: 'Issuer'
+    sub: 'Subject'
+    aud: 'Audience'
+    exp: 'Expiration Time'
+    nbf: 'Not Before'
+    iat: 'Issued At'
+    jti: 'JWT ID'
+    name: 'Full name'
+    givenName: 'Given name(s) or first name(s)'
+    familyName: 'Surname(s) or last name(s)'
+    middleName: 'Middle name(s)'
+    nickname: 'Casual name'
+    preferredUsername: 'Shorthand name by which the End-User wishes to be referred to'
+    profile: 'Profile page URL'
+    picture: 'Profile picture URL'
+    website: 'Web page or blog URL'
+    email: 'Preferred e-mail address'
+    emailVerified: 'True if the e-mail address has been verified; otherwise false'
+    gender: 'Gender'
+    birthdate: 'Birthday'
+    zoneinfo: 'Time zone'
+    locale: 'Locale'
+    phoneNumber: 'Preferred telephone number'
+    phoneNumberVerified: 'True if the phone number has been verified; otherwise false'
+    address: 'Preferred postal address'
+    updatedAt: 'Time the information was last updated'
+    azp: 'Authorized party - the party to which the ID Token was issued'
+    nonce: 'Value used to associate a Client session with an ID Token'
+    authTime: 'Time when the authentication occurred'
+    atHash: 'Access Token hash value'
+    cHash: 'Code hash value'
+    acr: 'Authentication Context Class Reference'
+    amr: 'Authentication Methods References'
+    subJwk: 'Public key used to check the signature of an ID Token'
+    cnf: 'Confirmation'
+    sipFromTag: 'SIP From tag header field parameter value'
+    sipDate: 'SIP Date header field value'
+    sipCallid: 'SIP Call-Id header field value'
+    sipCseqNum: 'SIP CSeq numeric header field parameter value'
+    sipViaBranch: 'SIP Via branch header field parameter value'
+    orig: 'Originating Identity String'
+    dest: 'Destination Identity String'
+    mky: 'Media Key Fingerprint String'
+    events: 'Security Events'
+    toe: 'Time of Event'
+    txn: 'Transaction Identifier'
+    rph: 'Resource Priority Header Authorization'
+    sid: 'Session ID'
+    vot: 'Vector of Trust value'
+    vtm: 'Vector of Trust trustmark URL'
+    attest: 'Attestation level as defined in SHAKEN framework'
+    origid: 'Originating Identifier as defined in SHAKEN framework'
+    act: 'Actor'
+    scope: 'Scope Values'
+    clientId: 'Client Identifier'
+    mayAct: 'Authorized Actor - the party that is authorized to become the actor'
+    jcard: 'jCard data'
+    atUseNbr: 'Number of API requests for which the access token can be used'
+    div: 'Diverted Target of a Call'
+    opt: 'Original PASSporT (in Full Form)'
+    vc: 'Verifiable Credential as specified in the W3C Recommendation'
+    vp: 'Verifiable Presentation as specified in the W3C Recommendation'
+    sph: 'SIP Priority header field'
+    aceProfile: 'ACE profile a token is supposed to be used with.'
+    cnonce: 'Client nonce'
+    exi: 'Expires in'
+    roles: 'Roles'
+    groups: 'Groups'
+    entitlements: 'Entitlements'
+    tokenIntrospection: 'Token introspection response'
diff --git a/src/tools/jwt-parser/locales/zh.yml b/src/tools/jwt-parser/locales/zh.yml
new file mode 100644
index 00000000..66f77a4b
--- /dev/null
+++ b/src/tools/jwt-parser/locales/zh.yml
@@ -0,0 +1,98 @@
+tools:
+  jwt-parser:
+    title: JWT 解析器
+    description: 解析和解码您的 JSON Web Token (jwt) 并显示其内容。
+
+    label: 要解码的 JWT
+    placeholder: 在这里放置您的令牌...
+    header: 头部
+    payload: 负载
+
+    invalidJWT: 无效的 JWT
+
+    HS256: '使用 SHA-256 的 HMAC'
+    HS384: '使用 SHA-384 的 HMAC'
+    HS512: '使用 SHA-512 的 HMAC'
+    RS256: '使用 SHA-256 的 RSASSA-PKCS1-v1_5'
+    RS384: '使用 SHA-384 的 RSASSA-PKCS1-v1_5'
+    RS512: '使用 SHA-512 的 RSASSA-PKCS1-v1_5'
+    ES256: '使用 P-256 和 SHA-256 的 ECDSA'
+    ES384: '使用 P-384 和 SHA-384 的 ECDSA'
+    ES512: '使用 P-521 和 SHA-512 的 ECDSA'
+    PS256: '使用 SHA-256 和具有 SHA-256 的 MGF1 的 RSASSA-PSS'
+    PS384: '使用 SHA-384 和具有 SHA-384 的 MGF1 的 RSASSA-PSS'
+    PS512: '使用 SHA-512 和具有 SHA-512 的 MGF1 的 RSASSA-PSS'
+    none: '未执行数字签名或 MAC'
+
+    typ: '类型'
+    alg: '算法'
+    iss: '签发者'
+    sub: '主题'
+    aud: '受众'
+    exp: '过期时间'
+    nbf: '不早于'
+    iat: '签发时间'
+    jti: 'JWT ID'
+    name: '全名'
+    givenName: '名字'
+    familyName: '姓氏'
+    middleName: '中间名'
+    nickname: '昵称'
+    preferredUsername: '用户希望被称呼的简称'
+    profile: '个人资料页面 URL'
+    picture: '个人资料图片 URL'
+    website: '网页或博客 URL'
+    email: '首选电子邮件地址'
+    emailVerified: '如果电子邮件地址已经验证为 true;否则为 false'
+    gender: '性别'
+    birthdate: '生日'
+    zoneinfo: '时区'
+    locale: '区域设置'
+    phoneNumber: '首选电话号码'
+    phoneNumberVerified: '如果电话号码已经验证为 true;否则为 false'
+    address: '首选邮寄地址'
+    updatedAt: '信息上次更新时间'
+    azp: '授权方 - 发出 ID 令牌的一方'
+    nonce: '用于将客户端会话与 ID 令牌关联的值'
+    authTime: '认证发生时间'
+    atHash: '访问令牌哈希值'
+    cHash: '代码哈希值'
+    acr: '认证上下文类引用'
+    amr: '认证方法引用'
+    subJwk: '用于验证 ID 令牌签名的公钥'
+    cnf: '确认'
+    sipFromTag: 'SIP From 标签头字段参数值'
+    sipDate: 'SIP 日期头字段值'
+    sipCallid: 'SIP Call-Id 头字段值'
+    sipCseqNum: 'SIP CSeq 数字头字段参数值'
+    sipViaBranch: 'SIP Via 分支头字段参数值'
+    orig: '原始身份字符串'
+    dest: '目标身份字符串'
+    mky: '媒体密钥指纹字符串'
+    events: '安全事件'
+    toe: '事件时间'
+    txn: '交易标识符'
+    rph: '资源优先级头授权'
+    sid: '会话 ID'
+    vot: '信任向量值'
+    vtm: '信任向量标记 URL'
+    attest: 'SHAKEN 框架中定义的证明级别'
+    origid: 'SHAKEN 框架中定义的起始标识符'
+    act: '操作者'
+    scope: '范围值'
+    clientId: '客户端标识符'
+    mayAct: '授权操作者 - 被授权成为操作者的一方'
+    jcard: 'jCard 数据'
+    atUseNbr: '访问令牌可用于的 API 请求次数'
+    div: '呼叫的被转移目标'
+    opt: '原始 PASSporT(完整形式)'
+    vc: '根据 W3C 推荐规范指定的可验证凭证'
+    vp: '根据 W3C 推荐规范指定的可验证展示'
+    sph: 'SIP 优先级头字段'
+    aceProfile: 'ACE 配置文件应与之一起使用的令牌'
+    cnonce: '客户端随机数'
+    exi: '剩余时间'
+    roles: '角色'
+    groups: '组'
+    entitlements: '权利'
+    tokenIntrospection: '令牌内省响应'
diff --git a/src/tools/keycode-info/index.ts b/src/tools/keycode-info/index.ts
index a9ffab2d..fa8ea17c 100644
--- a/src/tools/keycode-info/index.ts
+++ b/src/tools/keycode-info/index.ts
@@ -1,10 +1,11 @@
 import { Keyboard } from '@vicons/tabler';
 import { defineTool } from '../tool';
+import { translate as t } from '@/plugins/i18n.plugin';
 
 export const tool = defineTool({
-  name: 'Keycode info',
+  name: t('tools.keycode-info.title'),
   path: '/keycode-info',
-  description: 'Find the javascript keycode, code, location and modifiers of any pressed key.',
+  description: t('tools.keycode-info.description'),
   keywords: [
     'keycode',
     'info',
diff --git a/src/tools/keycode-info/keycode-info.vue b/src/tools/keycode-info/keycode-info.vue
index a999d8ae..420e9c76 100644
--- a/src/tools/keycode-info/keycode-info.vue
+++ b/src/tools/keycode-info/keycode-info.vue
@@ -5,6 +5,8 @@ import InputCopyable from '../../components/InputCopyable.vue';
 
 const event = ref();
 
+const { t } = useI18n();
+
 useEventListener(document, 'keydown', (e) => {
   event.value = e;
 });
@@ -16,28 +18,28 @@ const fields = computed(() => {
 
   return [
     {
-      label: 'Key :',
+      label: t('tools.keycode-info.keyLabel'),
       value: event.value.key,
-      placeholder: 'Key name...',
+      placeholder: t('tools.keycode-info.keyPlaceholder'),
     },
     {
-      label: 'Keycode :',
+      label: t('tools.keycode-info.keycodeLabel'),
       value: String(event.value.keyCode),
-      placeholder: 'Keycode...',
+      placeholder: t('tools.keycode-info.keycodePlaceholder'),
     },
     {
-      label: 'Code :',
+      label: t('tools.keycode-info.codeLabel'),
       value: event.value.code,
-      placeholder: 'Code...',
+      placeholder: t('tools.keycode-info.codePlaceholder'),
     },
     {
-      label: 'Location :',
+      label: t('tools.keycode-info.locationLabel'),
       value: String(event.value.location),
-      placeholder: 'Code...',
+      placeholder: t('tools.keycode-info.locationPlaceholder'),
     },
 
     {
-      label: 'Modifiers :',
+      label: t('tools.keycode-info.modifiersLabel'),
       value: [
         event.value.metaKey && 'Meta',
         event.value.shiftKey && 'Shift',
@@ -46,7 +48,7 @@ const fields = computed(() => {
       ]
         .filter(Boolean)
         .join(' + '),
-      placeholder: 'None',
+      placeholder: t('tools.keycode-info.modifiersPlaceholder'),
     },
   ];
 });
@@ -59,7 +61,7 @@ const fields = computed(() => {
         {{ event.key }}
       
       
-        Press the key on your keyboard you want to get info about this key
+        {{ t('tools.keycode-info.tips') }}
       
     
 
diff --git a/src/tools/keycode-info/locales/en.yml b/src/tools/keycode-info/locales/en.yml
index 98322a55..dbae839f 100644
--- a/src/tools/keycode-info/locales/en.yml
+++ b/src/tools/keycode-info/locales/en.yml
@@ -2,3 +2,16 @@ tools:
   keycode-info:
     title: Keycode info
     description: Find the javascript keycode, code, location and modifiers of any pressed key.
+
+    keyLabel: 'Key :'
+    keyPlaceholder: 'Key name...'
+    keycodeLabel: 'Keycode :'
+    keycodePlaceholder: 'Keycode...'
+    codeLabel: 'Code :'
+    codePlaceholder: 'Code...'
+    locationLabel: 'Location :'
+    locationPlaceholder: 'Code...'
+    modifiersLabel: 'Modifiers :'
+    modifiersPlaceholder: 'None'
+
+    tips: Press the key on your keyboard you want to get info about this key
diff --git a/src/tools/keycode-info/locales/zh.yml b/src/tools/keycode-info/locales/zh.yml
new file mode 100644
index 00000000..80b5eac4
--- /dev/null
+++ b/src/tools/keycode-info/locales/zh.yml
@@ -0,0 +1,17 @@
+tools:
+  keycode-info:
+    title: 按键信息
+    description: 查找任何按键的 JavaScript 按键码、代码、位置和修饰键。
+
+    keyLabel: '按键:'
+    keyPlaceholder: '按键名称...'
+    keycodeLabel: '按键码:'
+    keycodePlaceholder: '按键码...'
+    codeLabel: '代码:'
+    codePlaceholder: '代码...'
+    locationLabel: '位置:'
+    locationPlaceholder: '位置...'
+    modifiersLabel: '修饰键:'
+    modifiersPlaceholder: '无'
+
+    tips: 按下您键盘上想要获取信息的按键
diff --git a/src/tools/slugify-string/index.ts b/src/tools/slugify-string/index.ts
index 8dabcdb1..07ee16bc 100644
--- a/src/tools/slugify-string/index.ts
+++ b/src/tools/slugify-string/index.ts
@@ -1,10 +1,11 @@
 import { AbcRound } from '@vicons/material';
 import { defineTool } from '../tool';
+import { translate as t } from '@/plugins/i18n.plugin';
 
 export const tool = defineTool({
-  name: 'Slugify string',
+  name: t('tools.slugify-string.title'),
   path: '/slugify-string',
-  description: 'Make a string url, filename and id safe.',
+  description: t('tools.slugify-string.description'),
   keywords: ['slugify', 'string', 'escape', 'emoji', 'special', 'character', 'space', 'trim'],
   component: () => import('./slugify-string.vue'),
   icon: AbcRound,
diff --git a/src/tools/slugify-string/locales/en.yml b/src/tools/slugify-string/locales/en.yml
index 7161b20d..fe2fdd37 100644
--- a/src/tools/slugify-string/locales/en.yml
+++ b/src/tools/slugify-string/locales/en.yml
@@ -2,3 +2,11 @@ tools:
   slugify-string:
     title: Slugify string
     description: Make a string url, filename and id safe.
+
+    inputLabel: Your string to slugify
+    inputPlaceholder: 'Put your string here (ex: My file path)'
+    outputLabel: Your slug
+    outputPlaceholder: 'You slug will be generated here (ex: my-file-path)'
+    copyBtn: Copy slug
+
+    copied: Slug copied to clipboard
diff --git a/src/tools/slugify-string/locales/zh.yml b/src/tools/slugify-string/locales/zh.yml
new file mode 100644
index 00000000..925ae6e6
--- /dev/null
+++ b/src/tools/slugify-string/locales/zh.yml
@@ -0,0 +1,12 @@
+tools:
+  slugify-string:
+    title: 字符串转换为 Slug
+    description: 将字符串转换为 URL、文件名和 ID 安全的格式。
+
+    inputLabel: 要转换为 Slug 的字符串
+    inputPlaceholder: '在此输入您的字符串(例如:我的文件路径)'
+    outputLabel: 您的 Slug
+    outputPlaceholder: '您的 Slug 将在此生成(例如:my-file-path)'
+    copyBtn: 复制 Slug
+
+    copied: Slug 已复制到剪贴板
diff --git a/src/tools/slugify-string/slugify-string.vue b/src/tools/slugify-string/slugify-string.vue
index f7666e30..82b44ec8 100644
--- a/src/tools/slugify-string/slugify-string.vue
+++ b/src/tools/slugify-string/slugify-string.vue
@@ -3,20 +3,21 @@ import slugify from '@sindresorhus/slugify';
 import { withDefaultOnError } from '@/utils/defaults';
 import { useCopy } from '@/composable/copy';
 
+const { t } = useI18n();
 const input = ref('');
 const slug = computed(() => withDefaultOnError(() => slugify(input.value), ''));
-const { copy } = useCopy({ source: slug, text: 'Slug copied to clipboard' });
+const { copy } = useCopy({ source: slug, text: t('tools.slugify-string.copied') });
 
 
 
   
-    
+    
 
-    
+    
 
     
       
-        Copy slug
+        {{ t('tools.slugify-string.copyBtn') }}