URL Encoder / Decoder
Encode special characters for URLs or decode percent-encoded strings back to readable text.
Developer
100% Free
Runs in Browser
Preview
Source Code
Toggle the controls below the code to live-edit the initial state values.
url-codec.tsx
import { useState } from "react";
import { Textarea } from "@/components/ui/textarea";
import { Button } from "@/components/ui/button";
import { Copy, Check, ArrowDown, ArrowUp } from "lucide-react";
export default function UrlCodec() {
const [input, setInput] = useState("");
const [output, setOutput] = useState("");
const [mode, setMode] = useState<"encode" | "decode">("encode");
const [error, setError] = useState("");
const [copied, setCopied] = useState(false);
const process = () => {
try {
if (mode === "encode") {
setOutput(encodeURIComponent(input));
} else {
setOutput(decodeURIComponent(input));
}
setError("");
} catch {
setError("Invalid input for " + mode + "ing");
setOutput("");
}
};
const copyOutput = async () => {
await navigator.clipboard.writeText(output);
setCopied(true);
setTimeout(() => setCopied(false), 1500);
};
return (
<div className="space-y-4">
<div className="flex gap-2">
<Button
variant={mode === "encode" ? "default" : "outline"}
onClick={() => setMode("encode")}
>
Encode
</Button>
<Button
variant={mode === "decode" ? "default" : "outline"}
onClick={() => setMode("decode")}
>
Decode
</Button>
</div>
<Textarea
placeholder={
mode === "encode"
? "Enter URL or text to encode..."
: "Enter URL-encoded string to decode..."
}
value={input}
onChange={(e) => setInput(e.target.value)}
className="min-h-[120px] resize-y font-mono text-sm"
/>
<Button onClick={process}>
{mode === "encode" ? (
<ArrowDown className="mr-2 h-4 w-4" />
) : (
<ArrowUp className="mr-2 h-4 w-4" />
)}
{mode === "encode" ? "Encode" : "Decode"}
</Button>
{error && (
<div className="rounded-lg border border-destructive/50 bg-destructive/10 p-3">
<p className="text-sm text-destructive">{error}</p>
</div>
)}
{output && (
<div className="relative rounded-lg border bg-muted/50 p-4">
<pre className="overflow-x-auto whitespace-pre-wrap break-all text-sm font-mono">
{output}
</pre>
<Button
variant="ghost"
size="icon"
className="absolute top-2 right-2"
onClick={copyOutput}
>
{copied ? <Check className="h-4 w-4" /> : <Copy className="h-4 w-4" />}
</Button>
</div>
)}
</div>
);
}
Props Playground
2 props
Required Libraries
Install the external dependencies used by this tool.
bun add lucide-react react
Shadcn UI Setup
Add the required Shadcn UI primitives to your project.
bun x --bun shadcn@latest add button textarea
Shadcn UI Components
The following primitives are required in your
@/components/ui
directory.
| Component | Import Path |
|---|---|
| button | @/components/ui/button |
| textarea | @/components/ui/textarea |
Imports
All import statements used in this tool.
| Source | Exports |
|---|---|
| react | useState |
| @/components/ui/textarea | Textarea |
| @/components/ui/button | Button |
| lucide-react | Copy, Check, ArrowDown, ArrowUp |
State Management
React state variables managed within this tool.
| Variable | Initial Value |
|---|---|
| input | "" |
| output | "" |
| mode | "encode" |
| error | "" |
| copied | false |
Functional Logic
Internal functions that handle the tool's core logic.
| Function | Parameters | Async |
|---|---|---|
| process() | None | No |
| copyOutput() | None |
Yes
|
External Resources
Documentation, tutorials, and package details for libraries used in this tool.