diff --git a/src/tools/index.ts b/src/tools/index.ts
index 73505234..7cfa07e3 100644
--- a/src/tools/index.ts
+++ b/src/tools/index.ts
@@ -10,6 +10,7 @@ import { tool as bip39 } from './bip39-generator';
 import { tool as dateTimeConverter } from './date-time-converter';
 import { tool as gitMemo } from './git-memo';
 import { tool as baseConverter } from './integer-base-converter';
+import { tool as urlEncoder } from './url-encoder';
 
 export const toolsByCategory: ToolCategory[] = [
   {
@@ -22,6 +23,11 @@ export const toolsByCategory: ToolCategory[] = [
     icon: LockOpen,
     components: [dateTimeConverter, baseConverter, romanNumeralConverter],
   },
+  {
+    name: 'Web',
+    icon: LockOpen,
+    components: [urlEncoder],
+  },
   {
     name: 'Development',
     icon: LockOpen,
diff --git a/src/tools/url-encoder/index.ts b/src/tools/url-encoder/index.ts
new file mode 100644
index 00000000..a7481245
--- /dev/null
+++ b/src/tools/url-encoder/index.ts
@@ -0,0 +1,11 @@
+import { Link } from '@vicons/tabler';
+import type { ITool } from '../Tool';
+
+export const tool: ITool = {
+  name: 'Encode/decode url formatted strings',
+  path: '/url-encoder',
+  description: 'Encode to url-encoded format (also known as "percent-encoded") or decode from it.',
+  keywords: ['url', 'encode', 'decode', 'percent', '%20', 'format'],
+  component: () => import('./url-encoder.vue'),
+  icon: Link,
+};
diff --git a/src/tools/url-encoder/url-encoder.vue b/src/tools/url-encoder/url-encoder.vue
new file mode 100644
index 00000000..221184d2
--- /dev/null
+++ b/src/tools/url-encoder/url-encoder.vue
@@ -0,0 +1,100 @@
+
+    
+        
+            
+                
+            
+
+            
+                
+            
+
+            
+                Copy
+            
+        
+        
+            
+                
+            
+
+            
+                
+            
+
+            
+                Copy
+            
+        
+    
+
+
+
+
+
\ No newline at end of file