;; where auth-type is WPA, WPA2, WEP, or nopass (for open networks). Escape reserved characters (backslash, semicolon, comma, colon, quotes) with a backslash if they appear in your SSID or password. Hidden networks need H:true and the SSID passed explicitly, since the phone can't discover the network by broadcasting.
Typical placements: framed poster near a coffee-shop counter, sticker on the back of a guest bedroom door in a rental, under the desk in a shared coworking space, on the WiFi router itself for household members. Security note: anyone who can see the printed QR code has your password, so don't post it in public-facing spaces for a network that also has access to sensitive LAN resources. For guest networks (isolated from internal traffic), the convenience usually outweighs the risk.
**Q: What goes in the WIFI: string exactly?**
A: WIFI:T:WPA;S:MyNetwork;P:MyPassword;;. T = security type (WPA, WPA2, WEP, or nopass). S = SSID. P = password. H = hidden (optional, true/false). Escape backslash, semicolon, comma, and colon with a backslash inside SSID or password values.
**Q: Does iOS support WiFi QR codes natively?**
A: Yes, since iOS 11 (2017). Point the camera at the code, tap the notification banner, and iOS joins the network — no password typed. Android 10+ supports the same format. Older Android versions need a dedicated scanner app.
**Q: Is a WiFi QR code less secure than typing the password?**
A: Functionally identical — the password is the same either way, just transferred differently. The risk shifts: instead of the password being written down on a sticky note, it's printed in a QR. Anyone who can photograph or scan the code has the password. For guest networks (isolated LAN), convenience wins.
**Q: Can I make a QR code for a hidden network?**
A: Yes — set H:true in the WIFI: string. The phone can't auto-discover the SSID, so the QR code supplies the network name explicitly and the phone joins directly. Without the H:true flag, the phone scans visible networks first and fails to find a hidden one.
#### vCard QR Code
URL: https://cleanweb.tools/tools/qr-code-generator/vcard
Spec: RFC 2426 (vCard 3.0)
A vCard QR code encodes a contact record in the vCard 3.0 format (RFC 2426) — the same format email clients and address-book apps have used for decades. When scanned, the phone prompts "Add [Name] to Contacts" and stores the record natively. It's the professional replacement for a paper business card: no typing, no OCR mistakes, no "I'll put that number in later" that never happens.
The encoded string starts with BEGIN:VCARD, lists fields line-by-line (FN for full name, ORG for organisation, TEL for phone, EMAIL for address, URL for website, TITLE for job title, ADR for address), and ends with END:VCARD. vCard 3.0 is the most widely supported version across iOS, Android, and macOS Contacts — vCard 4.0 exists but parsing is patchier on older devices. Multiple phone or email fields with different types (TEL;TYPE=WORK vs TEL;TYPE=CELL) are allowed.
Typical placements: printed business cards (next to or instead of text contact details), conference name badges, speaker slides during an introduction, email signatures (as a small inline image), trade-show booths. The QR is especially useful at networking events where attendees stack a dozen cards in an hour — a vCard scan lands the contact directly in Contacts, searchable forever, while paper cards sit in a drawer and get thrown out.
**Q: What vCard version should I use for QR codes?**
A: vCard 3.0 (RFC 2426) — the widest-supported format across iOS Contacts, Android Contacts, and macOS. vCard 4.0 is newer but parsing varies. 2.1 is archaic. Stick with 3.0 unless a specific system demands otherwise; every phone made this decade handles 3.0 correctly.
**Q: Can I include a photo in a vCard QR code?**
A: Technically yes (PHOTO;ENCODING=BASE64;TYPE=JPEG:...) but in practice no — embedding an image blows past a QR code's comfortable data limit and the resulting code becomes huge and hard to scan. If you need a photo, link to a URL (PHOTO;VALUE=URI:https://...) instead.
**Q: Will a vCard QR work on my business card?**
A: Yes — print it at ~15mm minimum on card stock. Put it on the back face with a "scan to save" label. At normal reading distance (~30cm), a 15mm code scans instantly. Don't shrink below that or thermal-printer jitter can corrupt enough modules to break the scan.
**Q: How many fields can I include?**
A: Dozens — name, nickname, multiple phones, multiple emails, address, organisation, title, URL, birthday, note. The practical ceiling is around 400 characters of content before the QR code needs high error-correction settings or becomes too dense to scan at card size. Keep the essentials; skip fax numbers and assistant info.
#### Text QR Code
URL: https://cleanweb.tools/tools/qr-code-generator/text
A plain-text QR code encodes arbitrary text that appears as-is when scanned. No URL scheme, no vCard structure, no WiFi auto-connect — the phone shows the decoded text and offers to copy it. Useful when you want the scan to hand off information rather than trigger an action: a seat-pairing assignment at a wedding, a password you want a user to verbalise, a puzzle clue, a serial number, a short poem printed on a card, a pickup code at a shop.
QR codes can technically encode a lot — up to 7,089 numeric digits or 4,296 alphanumeric characters in a single version-40 code at low error correction. In practice, aim for under 300 characters if you want a code that scans reliably from a phone camera at desk distance. Past that, the modules get small, error correction eats into capacity, and scans start failing on anything but perfectly-printed surfaces.
The scanning experience varies slightly by phone: iOS shows the text in a Safari-adjacent preview and offers "Copy". Android typically shows the text in a system scanner with a copy button. Neither auto-opens anything, which is why text is the safest default for non-URL content — no accidental navigation, no app prompts, just the raw string.
**Q: How much text can a QR code hold?**
A: Up to 4,296 alphanumeric characters theoretically, but pragmatically target under 300 for reliable scanning from a phone camera. More characters means tinier modules, which means scans fail on anything but perfectly-printed surfaces.
**Q: Does a text QR code open anything automatically?**
A: No — phones show the decoded text with a "copy" or "share" option but don't open any app or URL. That's the safety property of plain-text: no scheme, no accidental navigation, no app prompt. Users copy the text or read it manually.
**Q: Can I put code snippets in a QR?**
A: Yes, up to the length limit. Useful for workshop handouts where attendees can scan a short function signature, a config string, or a command to run. Paste it into your phone and forward via email or copy to your laptop. Large snippets should link to a gist instead.
**Q: Is the text in a plain QR visible to anyone who scans it?**
A: Yes — QR is not encryption. Any scanner (including passers-by with a camera app pointed at your printed code) decodes the text. Don't encode secrets in a text QR that's visible in public. For shared credentials, use a QR on a page that requires authentication to view.
---
## URL Slug Generator
URL: https://cleanweb.tools/tools/slug-generator
Tags: slug, url, seo, permalink, generator
Transform any text into clean, SEO-friendly URL slugs. Removes special characters, converts spaces to hyphens, and handles unicode characters. Essential for content management and blog posts.
### Features
- Convert any text into clean URL-friendly slugs
- Remove special characters and handle unicode
- Convert spaces to hyphens automatically
- Copy the generated slug to clipboard
### How to use
1. Type or paste your title or text into the input
2. View the generated slug in real-time
3. Adjust settings if needed for custom separators
4. Copy the slug for use in your CMS or website
### FAQ
**Q: Why are hyphens preferred over underscores in URL slugs?**
A: Google treats hyphens as word separators and underscores as part of the word. So "my-post" is read as "my post"; "my_post" is read as "mypost" and doesn't rank for "my" or "post" individually. Hyphens also look better in printed URLs and are easier to remember.
**Q: Should slugs be lowercase?**
A: Yes. HTTP paths are technically case-sensitive, but most routing treats /About and /about as the same page — except when it doesn't, and you end up with duplicate content. Lowercase slugs side-step that entirely. It's the default behaviour of every major CMS.
**Q: How long should a slug be?**
A: Short enough to read, long enough to carry your 1–2 primary keywords. 3–6 words is typical; 40–60 characters is a good ceiling. Slugs longer than that get truncated in shares and look spammy. Strip stop words ("the", "a", "of") unless they change the meaning.
**Q: What does the generator do with accented characters?**
A: It transliterates them to ASCII equivalents by default (é → e, ü → u, ñ → n). That's the right default for English indexing — Google normalises accented characters anyway. If your audience is non-English, keep the accents; modern browsers handle Unicode URLs fine.
**Q: Can I change a slug after the post is published?**
A: You can, but don't without a 301 redirect from the old slug. Changing URLs invalidates external links, SERP rankings, and social shares. Most CMSs auto-create redirects when you edit a slug; confirm yours does before changing anything already indexed.
---
## Social Preview Generator
URL: https://cleanweb.tools/tools/social-previews
Tags: social media, preview, mockup, screenshot, og image, twitter
Generate stunning social media preview images by placing your website screenshots in a sleek MacBook-style laptop frame. Choose from beautiful gradient backgrounds, select the perfect size for Twitter, LinkedIn, Facebook, and more. Export as high-quality PNG for your social sharing needs.
### Features
- Create social media preview images with laptop mockups
- Choose from beautiful gradient backgrounds
- Select preset sizes for Twitter, LinkedIn, and Facebook
- Export as high-quality PNG images
### How to use
1. Upload a screenshot of your website or app
2. Select a background style and size preset
3. Preview the mockup with your screenshot
4. Export and download the image for social media
### FAQ
**Q: What image size should I export for each platform?**
A: Twitter/X: 1200×675 (16:9). LinkedIn: 1200×627. Facebook: 1200×630. Instagram feed: 1080×1080 (1:1) or 1080×1350 (4:5). The tool includes presets for all of these. Most platforms downscale gracefully, so 1200×630 is a safe universal size.
**Q: Do I need a laptop mockup, or does a plain screenshot work?**
A: Plain screenshots work but blend into noisy feeds. Mockups add visual context (this is a website, not just a photo) and make the preview feel intentional rather than improvised. For product launches and portfolio shares, mockups convert better; for quick announcements, a plain screenshot is fine.
**Q: Can I use my own background image?**
A: The current version ships gradient presets. For brand-consistent backgrounds (textured, photographic, or branded colour blocks), import your exported image into a design tool like Figma and add it there. Gradients cover 80% of the need; bespoke backgrounds belong in a design workflow.
**Q: Where does my screenshot go after I upload it?**
A: Nowhere — the image stays in your browser and is never uploaded. The preview, the mockup composition, and the exported PNG all happen client-side via the Canvas API. Useful for unreleased product screenshots that shouldn't leak to a third party.
**Q: Why does my PNG look pixelated on Retina displays?**
A: You're exporting at 1× resolution for a 2× display. For crisp rendering on modern laptops and phones, export at 2× — a 1200×630 canvas exports as 2400×1260. The extra pixels cost nothing to the user (modern connections swallow it) and look correct everywhere.
---
# Text & Content
Index: https://cleanweb.tools/tools/category/text
## Lorem Ipsum Generator
URL: https://cleanweb.tools/tools/lorem-ipsum-generator
Tags: lorem ipsum, placeholder, text, content, mockup
Produce classical Lorem Ipsum filler in the exact shape your mockup needs — a three-word headline, a single 20-word sentence, a three-paragraph article body, or a long scroll for stress-testing scroll-restoration logic. The generator is deliberately boring: the same Lorem Ipsum corpus every other design tool uses, so stakeholders immediately recognise it as placeholder instead of confusing it for real copy. Paragraph length varies naturally so type-set mockups don't look suspiciously uniform. Handy for Figma exports that need longer text than the plugin provides, React components wired up before the copywriter is ready, email templates being QA'd for line-wrap behaviour, and CMS seeds that need hundreds of dummy entries. No API calls, no rate limits — generate as much or as little as you like.
### Features
- Generate paragraphs, sentences, or words of placeholder text
- Customize the amount of text generated
- Copy generated text to clipboard instantly
- Standard Lorem Ipsum text for professional mockups
### How to use
1. Select the type of text output: paragraphs, sentences, or words
2. Set the desired quantity
3. Click "Generate" to create placeholder text
4. Copy the result to use in your designs
### FAQ
**Q: Where does Lorem Ipsum actually come from?**
A: It's a scrambled passage from Cicero's De finibus bonorum et malorum, written around 45 BC. A typesetter in the 1500s reshuffled the words into the nonsense block designers have used as placeholder text ever since — exactly because it reads as text-shaped but nobody mistakes it for meaning.
**Q: Should I ever ship a site with Lorem Ipsum?**
A: No — search engines will index it, and real users will see it if a CMS field goes missing. Treat it as pre-production scaffolding only. Before launch, replace every instance with real copy and grep the codebase for "lorem" to be sure nothing slipped through.
**Q: Does Lorem Ipsum work for non-Latin scripts?**
A: Not really. It tests glyph width and line-height for Latin scripts but tells you nothing about how Cyrillic, Arabic, CJK, or Indic fonts will wrap. For those, use a language-appropriate placeholder — "текст-рыба" for Russian, 龍虎山 patterns for Chinese, etc.
**Q: How is this different from a random-word generator?**
A: Lorem Ipsum is a fixed corpus — the same words and sentence patterns every tool produces. That uniformity is the point: it's universally recognised as placeholder, so designers and stakeholders don't mistake it for real copy. Random-word generators look more like text but confuse readers.
**Q: Can I use Lorem Ipsum with screen-reader testing?**
A: Only cautiously. Screen readers will happily pronounce "Lorem ipsum dolor sit amet" in garbled pseudo-Latin, which doesn't represent how your final content sounds. For accessibility QA, swap in real-language placeholder or the actual copy before testing focus order and announcements.
### Variants
#### Lorem Ipsum Paragraphs
URL: https://cleanweb.tools/tools/lorem-ipsum-generator/paragraphs
Paragraph-level Lorem Ipsum is the format most designers reach for first — it gives you the natural rhythm of a written article: short intro sentences, longer middle paragraphs, varied sentence counts per paragraph. The generator produces 4–8 sentences per paragraph, with sentence lengths varying between 8 and 18 words, so your typeset mockup shows the realistic block shapes real content will produce rather than the suspiciously-uniform rectangles that hand-written placeholder gives.
Use paragraphs when you're laying out long-form content: a blog post template, an article body, an email newsletter, a product page that has a multi-paragraph description, a CMS preview, a privacy-policy-shaped legal page. The first paragraph always starts "Lorem ipsum dolor sit amet, consectetur adipiscing elit." because that's the canonical opening every stakeholder recognises as placeholder.
Don't use paragraphs for: form labels, button copy, menu items (use sentences or words instead — paragraphs make them look like descriptions), or anywhere the final content will be short. Mismatching the length of placeholder to the length of the final copy misleads design reviews.
**Q: How long is a Lorem Ipsum paragraph?**
A: The generator produces 4–8 sentences per paragraph, each sentence 8–18 words. That gives an average paragraph length of around 80–140 words — close to real article writing. Real blog-post paragraphs typically run shorter (50–80 words); Lorem is slightly weightier to test layout with denser-than-average content.
**Q: Do I get the same text every time?**
A: No — each generation randomly picks words from the Lorem corpus, so identical counts produce different output. That's deliberate: you want to stress-test layout with content that differs from run to run, not memorise a single block. The first sentence is always "Lorem ipsum dolor sit amet…" to keep the placeholder instantly recognisable.
**Q: Should I ship a page with paragraph Lorem Ipsum?**
A: Never. Search engines will index it, real users will see placeholder if a CMS field goes missing, and "lorem ipsum" typically appears in both real copy and sample text, making grep-cleanup error-prone. Replace every placeholder block with real content before launch and audit the codebase for "lorem" as a final check.
#### Lorem Ipsum Sentences
URL: https://cleanweb.tools/tools/lorem-ipsum-generator/sentences
Sentence-level Lorem Ipsum is the right choice when the final content will be a short fragment rather than a multi-paragraph block. Each sentence is 8–18 words, ending with a period. The generator produces the exact number of sentences requested, separated by single spaces (joinable into one paragraph) rather than double newlines.
Typical uses: product card summaries on a grid (three sentences each), form field help text (one sentence), tooltips (one short sentence), search result snippets (2–3 sentences), email subject lines (one sentence), UX copy in dialogs and confirmation screens, navigation descriptions in a sitemap mockup, or any component where a full paragraph would overflow the intended container.
Why sentences over words: using 15 bare words produces a jarring no-period block that looks like garbage. Sentences are the smallest natural unit of prose; designers reviewing the mockup read them like real copy instead of parsing them like a data dump. For counters and form values, use the word variant; for any display text, use sentences.
**Q: How long is a typical Lorem Ipsum sentence?**
A: 8–18 words, randomly varied per sentence. That matches the natural range of English prose sentences (short punchy ones plus longer explanatory ones). Each sentence starts capitalised and ends with a period, like well-formed copy.
**Q: Can I generate a single sentence for a tooltip?**
A: Yes — request 1 sentence. The generator produces one 8–18-word Latin sentence, which is about the right length for a tooltip or helper caption. For very short tooltips, generate one and trim to the first clause, or use the words variant for a sub-sentence fragment.
**Q: Are the sentences grammatically Latin?**
A: No — Lorem Ipsum is intentionally mangled Latin. Real Latin readers recognise the Cicero origin but find the word order and grammar nonsensical. That's the design: sentences that read as text-shaped without being mistakable for real meaning in any language.
#### Lorem Ipsum Words
URL: https://cleanweb.tools/tools/lorem-ipsum-generator/words
Word-level Lorem Ipsum gives you raw bare word output without sentence structure. No capitalisation beyond the first word, no periods, just space-separated Latin words from the Lorem corpus. The generator produces the exact word count requested, so you can dial a mockup to fit a specific character-constrained component.
Use words for: headline length testing ("How does a 7-word headline look in this typography?"), button labels, tag and category labels, truncated preview text, character-limited form fields, navigation link text, card titles, placeholder metadata like author names or dates that need to have a specific word shape for layout testing. Also useful for content-hash-density tests — filling a table with varying word counts per cell to make sure column widths respond correctly.
Words is the least useful variant for paragraph-body layout testing: it misses the sentence-break rhythm real prose has. Reach for the sentences variant when you need short copy that still reads like writing, and the words variant when you explicitly want no sentence structure.
**Q: What's the average word length in Lorem Ipsum?**
A: About 6.3 characters — very close to average English word length (5.1 chars) plus typical Latin's slightly longer words. That's why Lorem is a good typographic stand-in: it approximates real English width without being mistaken for real English content.
**Q: Can I use this for card titles?**
A: Yes — pick a word count that matches the longest real title you expect (e.g., 5–7 words for product titles, 10–12 for blog post headlines) and see how the component handles it. Also try the single-word extreme ("a") to check what happens when titles are very short.
**Q: Why is only the first word capitalised?**
A: For readability. Word-only output without any capitalisation looks like a data dump; capitalising every word reads as Title Case, which misleads the layout review. Capitalising only the first word — sentence-like — is the middle ground: recognisable as placeholder without pretending to be anything else.
---
## Markdown Preview
URL: https://cleanweb.tools/tools/markdown-preview
Tags: markdown, preview, editor, documentation, readme
A live Markdown editor and previewer that renders your Markdown content in real-time. Perfect for writing documentation, README files, blog posts, and any content that uses Markdown formatting.
### Features
- Live Markdown rendering as you type
- Support for headings, lists, links, images, and code blocks
- Side-by-side editor and preview layout
- Copy rendered HTML or raw Markdown
### How to use
1. Type or paste Markdown content in the editor
2. View the rendered preview in real-time
3. Use the toolbar for common formatting shortcuts
4. Copy the output for your documentation or blog
### FAQ
**Q: Which flavour of Markdown does the preview use?**
A: CommonMark with GitHub-Flavored Markdown extensions: fenced code blocks, tables, task lists, strikethrough, and autolinks. Pure CommonMark parsers won't render GFM tables, so the preview may show slightly more than a renderer like Python-Markdown without extensions enabled.
**Q: Can I paste HTML inline?**
A: Yes — raw HTML is passed through, which is how GFM handles it too. Note that when you embed Markdown inside HTML, most parsers stop treating it as Markdown on the inside; wrap the Markdown block in a line break to re-activate parsing.
**Q: How do I render a Mermaid diagram or math?**
A: Not in this previewer. GitHub renders Mermaid and KaTeX with special fenced blocks, but that's a GitHub extension, not core Markdown. For math, prefix with $$ and render with KaTeX in your production site. For diagrams, embed a pre-rendered image.
**Q: Is my Markdown sent anywhere?**
A: No — the preview runs entirely client-side. Private READMEs, internal docs, and draft blog posts never leave your browser. That matters when your content references unshipped product code or unreleased dates.
**Q: Why doesn't a blank line do what I expect inside a list?**
A: Markdown treats two blank lines as ending the list. One blank line between items is a loose list (each item gets wrapping), zero is a tight list (bare text). If you need a paragraph inside an item, indent it 2–4 spaces under the bullet.
---
## Text Case Converter
URL: https://cleanweb.tools/tools/case-converter
Tags: text, case, convert, uppercase, lowercase
Transform text between various cases including uppercase, lowercase, title case, sentence case, camelCase, snake_case, and kebab-case. Perfect for developers and content creators.
### Features
- Convert text to uppercase, lowercase, or title case
- Support for camelCase, snake_case, and kebab-case
- Sentence case and other formatting options
- Copy converted text to clipboard instantly
### How to use
1. Paste or type your text into the input area
2. Click the desired case conversion button
3. View the converted text in the output area
4. Copy the result using the copy button
### FAQ
**Q: What's the difference between title case and sentence case?**
A: Title case capitalises most words in a title ("A Tale of Two Cities"). Sentence case only capitalises the first word and proper nouns ("A tale of two cities"). Most style guides prefer sentence case for headlines now because it reads faster; AP Style still uses title case.
**Q: How does the converter handle abbreviations like URL or API?**
A: It treats them as regular words unless you're converting from camelCase or PascalCase, where it tries to preserve acronym boundaries. For exact control over "userAPIClient" ↔ "user-api-client" vs "user-a-p-i-client", you may need to post-edit — there's no perfect automatic rule.
**Q: Why does my camelCase output have capital letters in the middle of numbers?**
A: Because digits create an implicit word boundary in most conversion algorithms. "version2Field" becomes "version-2-field", and round-tripping to camel gives "version2Field". If you want "version2field" instead, paste your string in snake_case first, then convert.
**Q: Is kebab-case the same as snake_case?**
A: Same concept, different separator. kebab-case uses hyphens (url-slug-generator), snake_case uses underscores (url_slug_generator). CSS class names, URLs, and npm package names tend to use kebab; Python variables and SQL columns tend to use snake.
**Q: Does this work for non-Latin alphabets?**
A: Mostly — upper and lowercase conversion works for any script with cased characters (Latin, Greek, Cyrillic). Scripts without case (Arabic, Hebrew, CJK, Devanagari) pass through unchanged. Tokenisation assumes whitespace separation, so CJK input won't split into "words" the way English does.
### Variants
#### camelCase
URL: https://cleanweb.tools/tools/case-converter/camel-case
camelCase is the dominant identifier convention in JavaScript, TypeScript, Java, Swift, and Kotlin. The first word is lowercase; every subsequent word starts with a capital letter; whitespace and punctuation disappear. So "user profile email" becomes "userProfileEmail", "first name" becomes "firstName", "API key" becomes "apiKey" (most conventions drop the all-caps treatment of acronyms beyond the first letter).
When to reach for camelCase: JavaScript object keys where you control the schema, TypeScript and Java variable names, Swift property names, React prop names (className, onClick, etc.), JSON payload fields where backend and frontend are both JS/TS. Don't use camelCase for CSS class names (use kebab-case), Python variables (use snake_case), or URL paths (use kebab-case) — those ecosystems have their own conventions that camelCase fights against.
Edge cases worth knowing: acronyms are handled differently across style guides. Google's JavaScript style guide says "parseHtml" (lowercase acronyms past the first letter); Microsoft and older Java conventions say "parseHTML" (all caps acronyms). Both are valid; consistency within a codebase matters more than choosing one over the other. The converter uses the more common "lowercase after first word" treatment.
**Q: How does camelCase differ from PascalCase?**
A: PascalCase capitalises every word including the first (UserProfile); camelCase lowercases the first word only (userProfile). JavaScript classes use PascalCase; variables, properties, and functions use camelCase. TypeScript keeps this rule. C# and .NET often use PascalCase for everything public.
**Q: Should acronyms like API and URL be all-caps in camelCase?**
A: Style guides split. Google JavaScript and modern TypeScript prefer "apiUrl" / "parseHtml". Older Java and Microsoft conventions prefer "APIUrl" / "parseHTML". Both parse correctly; pick one per codebase and stick to it. The converter uses lowercase-after-first-word, which is the more common modern choice.
**Q: What does camelCase do with numbers?**
A: Numbers get treated as word boundaries. "version 2 api" becomes "version2Api"; round-tripping gives you the same string. If you need the number glued without a capital break ("version2api"), convert to snake_case first (version_2_api), then post-process — there's no unambiguous single-step conversion.
**Q: Which ecosystem uses camelCase most?**
A: JavaScript and TypeScript (the dominant convention for variables, functions, and object keys). Java variable names. Swift properties. React component props. JSON API payloads generated by JS/TS backends. Python and Go explicitly avoid camelCase; PHP is split; C# uses PascalCase for most identifiers.
#### snake_case
URL: https://cleanweb.tools/tools/case-converter/snake-case
snake_case lowercases every word and joins them with underscores. "User Profile Email" becomes "user_profile_email"; "HTTP Request Count" becomes "http_request_count". Named after its visual resemblance to a snake slithering through the words, the format emerged in Unix shell scripting and C early on and became the dominant convention in Python, Ruby, Rust identifiers, and SQL column names.
When to use snake_case: Python variable and function names (PEP 8 is explicit on this), Ruby method names, Rust variable bindings (but not types — types use PascalCase), C/C++ names in older style guides, SQL column and table names (most style guides prefer snake_case because identifiers are case-insensitive by default in most databases, and underscores survive that normalisation better than camelCase does), environment variables derived from snake-cased identifiers (then uppercased to CONSTANT_CASE).
Don't use snake_case in JavaScript or TypeScript unless you're specifically matching a backend schema — the JS ecosystem has settled on camelCase and snake_case fights against linters, library conventions, and destructuring ergonomics. When bridging a Python backend to a JS frontend, pick one convention at the API boundary and normalise; don't mix them in application code.
**Q: Why do Python and Ruby prefer snake_case over camelCase?**
A: Historical: Guido van Rossum (Python) and Matz (Ruby) both came from backgrounds where underscores-between-words was already the Unix norm. PEP 8 codified it in 2001. Readability studies are inconclusive — both conventions parse fine for humans. Consistency within a language matters more than cross-language uniformity.
**Q: Should SQL column names be snake_case?**
A: Yes, almost universally. SQL identifiers are case-insensitive by default (Postgres folds to lowercase, MySQL to lowercase on Linux), so camelCase columns often lose their capitalisation and become unreadable. snake_case survives case-folding intact. Most ORM conventions (Django, SQLAlchemy, Rails Active Record) assume snake_case column names.
**Q: What about SCREAMING_SNAKE_CASE?**
A: That's CONSTANT_CASE — snake_case uppercased. Used for constants in Python (`MAX_RETRIES`), environment variables (`DATABASE_URL`), and module-level configuration. Same structure as snake_case, just uppercased. Convert to snake_case first, then uppercase, to handle edge cases cleanly.
**Q: Is snake_case an identifier in every language?**
A: Yes — underscores are valid identifier characters in every mainstream programming language, including JavaScript, C, Java, Go, Rust, Python, Ruby, PHP, and Kotlin. Whether the language's idiomatic style uses snake_case is another question, but the syntax always supports it.
#### kebab-case
URL: https://cleanweb.tools/tools/case-converter/kebab-case
kebab-case (also "spinal-case" or "train-case" in some style guides) lowercases words and joins them with hyphens. "User Profile Email" becomes "user-profile-email"; "API Request Count" becomes "api-request-count". Named after its resemblance to words skewered on a kebab, the format dominates in places where the identifier is also a surface the browser, search engine, or user interacts with: URLs, CSS class names, HTML attributes, and package names.
Why kebab-case over snake_case in the web world: URLs can't contain underscores in SEO-friendly slugs (Google treats hyphens as word separators and underscores as part of the word — "my_post" is read as "mypost", which doesn't rank for either "my" or "post"). CSS class names historically couldn't use camelCase reliably (pre-IE9 had case-handling quirks in class attribute matching), so the ecosystem settled on kebab. HTML attributes are case-insensitive and would corrupt camelCase; kebab survives intact.
Use kebab-case for: CSS class names, HTML data-attributes (data-user-id), URL path segments (/user-settings/account-email), npm package names (official policy — no uppercase, no underscores), URL query parameter keys in some APIs, CLI flag names (--dry-run), filenames for human-readable docs (user-guide.md), HTML custom element names (required to contain a hyphen per spec).
**Q: Why are npm package names required to use kebab-case?**
A: npm policy since the registry's earliest days: package names must be URL-safe and filesystem-safe across all major operating systems. That rules out uppercase (case-insensitive filesystems collide) and underscores (most package-name conventions in the wider JS world were already kebab). The policy is enforced at publish time.
**Q: Are hyphens better than underscores in URL slugs for SEO?**
A: Yes, and the difference is real. Google treats hyphens as word separators and underscores as part of the word. "my-post" is read as "my post" (ranking for both words); "my_post" is read as "mypost" (ranking for neither). Matt Cutts confirmed this in 2007 and the rule has never changed.
**Q: Can I use kebab-case in JavaScript variable names?**
A: No — the hyphen is a subtraction operator. `const user-id = 1` is a syntax error (or worse, a subtraction). Use kebab-case only in strings, URL paths, CSS class names, and HTML attributes. For identifiers, use camelCase.
**Q: What's the difference between kebab-case and "spinal-case"?**
A: Same thing, different nicknames. Some style guides and libraries use "spinal-case" or "train-case" interchangeably. They all mean lowercase words joined by hyphens. You'll see "kebab" most often in JS ecosystems, "spinal" occasionally in older documentation.
#### PascalCase
URL: https://cleanweb.tools/tools/case-converter/pascal-case
PascalCase capitalises the first letter of every word and removes whitespace and punctuation. "user profile form" becomes "UserProfileForm"; "http request context" becomes "HttpRequestContext". Named after the Pascal programming language (which used the style in its system identifiers), PascalCase is sometimes called "UpperCamelCase" to distinguish it from regular camelCase — which differs only in the first letter.
When to reach for PascalCase: JavaScript and TypeScript class names (UserProfile, HttpClient), React component names (a hard requirement — JSX treats lowercase tags as HTML elements and capitalised tags as components), TypeScript interface and type names (preferred by the official TS style guide), C# classes, properties, and public methods (.NET conventions use PascalCase for almost everything public), Go exported identifiers (Go uses initial-capital as the export-visibility marker, equivalent to PascalCase for multi-word names), Swift type names, Rust types and traits (but not variables, which use snake_case).
Acronym handling varies by style guide. Modern JavaScript and TypeScript favour "HttpRequest" / "ParseXml" (only first letter of acronyms capitalised beyond the initial word). Older .NET and Java style often prefer "HTTPRequest" / "ParseXML". Both parse the same; consistency per codebase matters more than picking the universally correct answer (there isn't one).
**Q: Is PascalCase the same as UpperCamelCase?**
A: Yes, exactly. PascalCase and UpperCamelCase are synonyms for the same style: first letter of every word capitalised, no separators. "PascalCase" is the more common name in modern documentation; "UpperCamelCase" still appears in older style guides (especially Sun's original Java conventions).
**Q: Why must React component names be PascalCase?**
A: JSX's naming rule: lowercase first letter = DOM element (
, ), capitalised first letter = React component (). Without this rule the transpiler can't tell components from elements. Naming a component "myButton" instead of "MyButton" will cause React to render nothing and silently fail.
**Q: What's the difference between PascalCase and Title Case?**
A: PascalCase has no whitespace ("UserProfile"). Title Case keeps whitespace ("User Profile"). Title Case is for display text (book titles, section headings); PascalCase is for identifiers. Converting from one to the other is just a question of whether you strip the spaces.
**Q: Do Python and Ruby use PascalCase for anything?**
A: Yes — class names. Python class naming (PEP 8) and Ruby class naming both use PascalCase (Python calls it CapWords, Ruby just follows the de-facto convention). Methods, variables, and constants in both languages use snake_case or CONSTANT_CASE, so the contrast between class name and method name is visual-grep-friendly.
#### Title Case
URL: https://cleanweb.tools/tools/case-converter/title-case
Title Case capitalises the first letter of every word and preserves whitespace between words. "the great gatsby" becomes "The Great Gatsby"; "war and peace" becomes "War And Peace". The convention is primarily for display text — book titles, movie titles, newspaper headlines, chapter names in reference works, and AP-Style headlines — rather than programming identifiers.
Title Case versus Sentence case: Title Case capitalises almost every word; Sentence case capitalises only the first word and proper nouns. Most style guides have moved toward Sentence case for headlines (BBC, The Guardian, much of modern web content) because it reads more quickly. AP Style, Chicago Manual of Style, and academic publishing still use Title Case for formal titles. There's no universally correct choice — match what your publication demands.
Edge cases: strict Title Case keeps articles ("a", "an", "the"), conjunctions ("and", "but", "or"), and short prepositions ("in", "on", "at") in lowercase unless they're the first or last word. "The Elements of Style" not "The Elements Of Style"; "War and Peace" not "War And Peace". Simple "capitalise every word" Title Case (sometimes called "first-letter capitalisation") doesn't follow these exceptions and produces the cruder "War And Peace" output. The converter uses the simpler rule — if your target is strict AP Style, manually downcase the short words.
**Q: Should I use Title Case or Sentence case for headlines?**
A: Title Case for formal contexts (book titles, academic papers, AP-Style newspapers, Chicago Style references). Sentence case for modern web content, blog posts, marketing copy, and most UX writing. BBC, The Guardian, and most tech publications have moved to Sentence case; it reads faster and looks less dated.
**Q: Does Title Case capitalise articles and short prepositions?**
A: Strict AP and Chicago styles don't — "The Elements of Style", "War and Peace", "Born in the USA". "A", "an", "the", "and", "but", "or", and short prepositions stay lowercase unless they're the first or last word. Casual "capitalise every word" Title Case ignores this and produces less-polished output.
**Q: What's the difference between Title Case and Headline Case?**
A: Functionally the same in most style guides. "Headline Case" sometimes refers specifically to AP Style's sentence-like capitalisation where even proper nouns follow the headline abbreviation rules. In practice most people use the terms interchangeably.
**Q: Does Title Case work for non-English languages?**
A: Partly. Germanic languages (English, German, Dutch) capitalise nouns in titles; Romance languages (French, Spanish, Italian) only capitalise the first word and proper nouns. The converter applies English-style Title Case; for French or Spanish titles, use Sentence case instead.
---
## Text Diff Checker
URL: https://cleanweb.tools/tools/diff-checker
Tags: diff, compare, text, changes, code review
Compare two blocks of text side-by-side and see exactly what changed. Highlights additions, deletions, and modifications. Perfect for code reviews, document comparison, and version tracking.
### Features
- Compare two blocks of text side-by-side
- Highlight additions, deletions, and modifications
- Line-by-line or inline diff view
- Perfect for code reviews and document comparison
### How to use
1. Paste the original text in the left panel
2. Paste the modified text in the right panel
3. View highlighted differences between the two texts
4. Use the diff output for code reviews or change tracking
### FAQ
**Q: What algorithm does the diff use?**
A: A variant of the Myers diff — the same algorithm Git and most diff tools implement. It finds the longest common subsequence between the two inputs in near-linear time and highlights everything else as added or deleted. For very long inputs (100 kB+), expect it to slow down.
**Q: Can I diff two JSON files structurally?**
A: This tool does a line-level text diff, which works on JSON but will flag reformatted-but-equivalent JSON as different. For true structural diff (order-independent, type-aware), use a dedicated JSON diff tool like json-diff or a VS Code extension; line diffing is coarser.
**Q: What's the difference between line diff and character diff?**
A: Line diff shows whole changed lines. Character diff highlights the specific characters within a line. Line diff reads faster for prose and code; character diff is better when the change is a typo or a single-word edit. This view defaults to line diff with inline character highlighting on changed lines.
**Q: Is my input stored?**
A: No — the diff runs entirely in-browser. That matters when you're comparing unreleased code, customer data, or confidential documents. Both pastes are held only in the open tab and disappear on refresh.
**Q: Why does git's diff look different than the one shown here?**
A: Git diffs include context lines (the default 3 lines above and below each change) and use unified-diff format. This view is more visual — side-by-side with highlighted changes. They're equivalent information, just rendered for different audiences.
---
# Converters
Index: https://cleanweb.tools/tools/category/converter
## Base64 Encoder & Decoder
URL: https://cleanweb.tools/tools/base64-encoder-decoder
Tags: base64, encode, decode, converter, developer
Convert between plain text (or binary) and Base64 without switching to a terminal. Useful when you need to drop a tiny SVG straight into a CSS background-image rule, decode a JWT payload to peek at its claims, unpack an email MIME part, or generate a Basic-Auth header from "user:pass" without reaching for btoa in the dev console. UTF-8 is handled correctly, so emoji, accented characters, and non-Latin scripts round-trip exactly — no double-encoded mojibake. The whole conversion happens in your browser, which matters when the string you're decoding is someone's session token or an Authorization header. Paste, toggle encode or decode, copy the result. Works on strings up to several megabytes; for larger binary files, use the CLI.
### Features
- Encode text to Base64 format instantly
- Decode Base64 strings back to plain text
- Handle UTF-8 characters correctly
- Copy encoded or decoded output to clipboard
### How to use
1. Paste your text or Base64 string into the input field
2. Select "Encode" or "Decode" mode
3. View the converted result instantly
4. Copy the output using the copy button
### FAQ
**Q: What's the difference between Base64 and base64url?**
A: Standard Base64 uses + and / as the 63rd and 64th characters and = for padding. base64url (RFC 4648 §5) swaps those for - and _ and usually drops the padding, so the output is safe to drop into URLs, filenames, and JWT parts without escaping.
**Q: Is Base64 encryption?**
A: No. Base64 is a 1:1 reversible encoding anyone can decode — treat the output as "plain text dressed up as ASCII", not as a secret. If you're encoding a password or API token, the token is still the secret; Base64 just makes it transport-safe.
**Q: Why is my Base64 output 33% longer than the input?**
A: Base64 represents every 3 bytes of input as 4 printable ASCII characters — a fixed 4/3 expansion, plus up to 2 padding characters. That's the price of going from an 8-bit alphabet to a 6-bit one; it's expected, not a bug.
**Q: Can I Base64-encode a binary file here?**
A: For text and short binary blobs yes, but for real file conversion use the Image-to-Base64 tool (for images) or a CLI like `base64 < file.bin` for large binaries — pasting a 50 MB file into a textarea won't end well.
**Q: Why does my decoded output look like random characters?**
A: Either the input wasn't actually Base64, or the decoded bytes aren't valid UTF-8 text. Try switching the output mode to binary or hex, or decode with a CLI like `echo '...' | base64 -d`. Some producers also use base64url; the leading `-` or `_` is a giveaway.
**Q: Is the Base64 I paste logged anywhere?**
A: No. Encoding and decoding both run entirely in the browser using btoa/atob — nothing is sent to a server or stored locally. That matters because Base64 is often used to smuggle secrets (JWTs, Basic-Auth headers), and those strings shouldn't land in server logs.
### Variants
#### Base64 Encode
URL: https://cleanweb.tools/tools/base64-encoder-decoder/encode
Spec: RFC 4648
Base64 encoding turns arbitrary bytes into a 64-character printable ASCII alphabet (A–Z, a–z, 0–9, +, /) plus the padding character =. Every 3 input bytes become 4 output characters — a fixed 4/3 expansion plus up to two padding bytes at the end. This encoder runs entirely in your browser via the native btoa API (with a UTF-8-aware wrapper for non-ASCII input), so secrets, tokens, and PII never leave the page.
Typical encoding uses: inlining a small SVG or PNG directly into a CSS `background-image: url(data:image/svg+xml;base64,...)` rule to eliminate an HTTP round-trip for a tiny asset; composing HTTP Basic-Auth headers from a "user:password" string; encoding a JWT header or payload segment before signing; embedding a file attachment in a JSON API body where binary would need a separate multipart upload; packing a binary blob into a URL query parameter or cookie value.
When not to use Base64: for any payload over a few hundred KB inside a JSON body — the 33% size expansion plus JSON string escaping makes it slow to parse and wasteful to transport. Use multipart/form-data or a direct binary upload instead. Never use Base64 as "encryption" — it's a 1:1 reversible encoding anyone can decode. The output is "printable ASCII dressed up to look secure", not a cipher.
**Q: Does Base64 encoding handle UTF-8 correctly?**
A: Yes — the encoder first converts your input to UTF-8 bytes (via TextEncoder), then Base64-encodes those bytes. Emoji, accented characters, and non-Latin scripts round-trip cleanly. Naive btoa("Ü") would throw; this tool handles it automatically.
**Q: Why is the output 33% longer than the input?**
A: Base64 represents every 3 bytes (24 bits) of input as 4 printable ASCII characters (24 bits spread across 4 × 6-bit symbols). That's a fixed 4/3 = 33% expansion, plus up to 2 "=" padding characters at the end. It's the cost of translating an 8-bit byte alphabet into a 6-bit printable alphabet.
**Q: When should I use base64url instead of standard Base64?**
A: Anywhere URL-unsafe characters would break things: URL path segments, query parameters, cookie values, JWT parts, filenames. base64url replaces + with -, / with _, and usually drops the = padding. The underlying bytes are the same; the output alphabet is the difference.
**Q: Can I encode a binary file here?**
A: Short binary blobs pasted as text work, but for actual files (images, PDFs, binary data) use the Image-to-Base64 tool which accepts file uploads via FileReader. For multi-megabyte files, a CLI like `base64 < file.bin` is faster and doesn't tie up your browser.
#### Base64 Decode
URL: https://cleanweb.tools/tools/base64-encoder-decoder/decode
Spec: RFC 4648
Base64 decoding is the inverse of encoding: 4 ASCII characters back to 3 bytes, with up to 2 padding characters at the end stripped. This decoder uses the native atob API with a UTF-8 wrapper, so you can paste Base64 that originally encoded Unicode text and get the right characters back. Everything runs in your browser — the Base64 you paste, the decoded output, and the decoded bytes never leave the page.
The common decoding flow: you have a JWT from an API response and want to peek at the claims (decode the middle segment, which is Base64-encoded JSON). You have an email MIME attachment and want to see what text it wrapped. You need to verify a Basic-Auth header by decoding "Basic " to "username:password". You received a data URL and want to extract the embedded content. You are debugging a backend that emits Base64 and want to confirm what it actually produced.
When the decoder fails: invalid characters (spaces, newlines, non-Base64 ASCII) slipped into the input; the input uses base64url (`-`, `_`) but the decoder is strict-standard; padding was stripped and the length isn't a multiple of 4; the decoded bytes aren't valid UTF-8 (binary data that decoded successfully but can't be rendered as text). Try switching to strict/lenient modes or trim the input to just the Base64 substring.
**Q: Why did my decoded output look like garbage?**
A: Either the input wasn't actually Base64 (some other encoding got there by mistake), or the decoded bytes weren't valid UTF-8 text (binary data that happens to decode successfully but doesn't render as characters). If you're decoding binary, switch to a hex-view tool; if you're decoding text, check the source encoding.
**Q: Can I decode a JWT here?**
A: You can decode the header and payload segments (the first two "."-separated parts) — both are base64url-encoded JSON. Paste one segment at a time. The signature (third part) is raw binary and won't decode to readable text. Dedicated JWT debuggers show all three at once.
**Q: What about base64url input with - and _ characters?**
A: Standard Base64 uses + and /; base64url substitutes - and _ to survive URL contexts. The decoder handles both: if your input has - or _, it's normalised back to + and / before decoding. Missing padding is also inferred from the input length.
**Q: Is decoding safe for sensitive data?**
A: Yes — the atob call and subsequent UTF-8 decoding happen entirely in the browser. No part of your Base64 input or the decoded output is sent anywhere. Safe for decoding session tokens, API keys, JWT payloads, and Basic-Auth headers.
---
## URL Encoder & Decoder
URL: https://cleanweb.tools/tools/url-encoder-decoder
Tags: url, encode, decode, uri, web
Encode special characters in URLs for safe transmission over the internet, or decode encoded URLs back to readable format. Essential for working with query strings, API parameters, and web development.
### Features
- Encode special characters for safe URL transmission
- Decode percent-encoded URLs back to readable text
- Handle all special and unicode characters
- Copy encoded or decoded output instantly
### How to use
1. Paste your URL or text into the input field
2. Select "Encode" or "Decode" mode
3. View the result instantly
4. Copy the output using the copy button
### FAQ
**Q: What's the difference between encodeURI and encodeURIComponent?**
A: encodeURI leaves structural characters (: / ? = & #) alone because it assumes you're encoding a whole URL. encodeURIComponent encodes them, because it assumes you're encoding a single query-parameter value. Use component when building query strings; use URI when passing a full URL through something picky.
**Q: Why is + in my decoded output a space?**
A: application/x-www-form-urlencoded (the format of HTML form submissions) encodes spaces as +, not %20. Browsers decode + to space on form posts. If the input came from a query string, that's right. If it came from a path, `+` is literal and shouldn't be converted.
**Q: Should slashes be encoded?**
A: Inside a query-parameter value: yes, as %2F, otherwise they'll be interpreted as a path boundary. Inside the path itself: no — encoding a slash changes the URL's meaning. The tool defaults to component-style encoding, which is the safe default for anything going after the ?.
**Q: Can I encode a URL that already has encoded parts?**
A: Double-encoding produces strings like %2520 (a %20 with the percent encoded again). The fix is to decode first, then re-encode. When in doubt, run the input through decode once and see if you get a readable URL back — if yes, encode that; if no, encode as-is.
**Q: Is my URL logged here?**
A: No — encoding and decoding run in your browser via encodeURIComponent and decodeURIComponent. That's worth noting because URLs often contain session tokens, auth codes, or OAuth state parameters you don't want captured in any third-party log.
### Variants
#### URL Encode
URL: https://cleanweb.tools/tools/url-encoder-decoder/encode
Spec: RFC 3986
URL encoding (also called percent-encoding, per RFC 3986) replaces reserved and non-ASCII characters with a "%XX" sequence, where XX is the two-digit hex value of the byte. A space becomes %20 (or + in form-data context), a question mark becomes %3F, an em-dash becomes %E2%80%94 (three bytes in UTF-8, each encoded). This encoder uses the browser's native encodeURIComponent, which encodes every character that isn't in the safe set — the right default for single query-parameter values.
Use the encoder when: building a query string programmatically and any of the values might contain reserved characters (?, &, =, #, +, /); constructing a path segment from user input that could include slashes you want to survive as literal characters; putting arbitrary text into a URL fragment (#foo bar) where the browser would otherwise mangle whitespace; generating OAuth state parameters or callback URLs where the embedded data must round-trip unchanged.
Don't use encodeURIComponent on a whole URL — it'll encode the structural characters (://, &, =) that need to stay literal for the URL to parse. Use encodeURI or manual parsing for that. The rule of thumb: encodeURIComponent for values, encodeURI for full URLs, URL constructor for anything structural.
**Q: Should I use encodeURI or encodeURIComponent?**
A: encodeURIComponent for single values (query parameter values, path segments); encodeURI for whole URLs that still have structural characters (://, &, =) that need to stay literal. This tool uses encodeURIComponent by default because "encode this text" usually means "for a value", not "for a whole URL".
**Q: Why are some characters like ~ and * not encoded?**
A: RFC 3986 includes them in the "unreserved" set — safe anywhere in a URL without encoding. The unreserved set is letters, digits, and - _ . ~. Older standards (RFC 2396) encoded * and ~, but modern tools follow RFC 3986 and leave them alone. Both forms decode identically.
**Q: How does URL encoding handle Unicode?**
A: Unicode characters are encoded as their UTF-8 byte sequence, each byte written as %XX. "€" (U+20AC) is encoded as %E2%82%AC — three percent-escaped bytes. The decoder reverses this automatically. Non-UTF-8 source encodings (Latin-1, Shift-JIS) don't round-trip without pre-conversion.
**Q: Why does a space become + in some contexts and %20 in others?**
A: Query strings historically encoded spaces as + (HTML form submissions use application/x-www-form-urlencoded, which defines + = space). Modern APIs use %20. Browsers decode both correctly on the URL's query portion, but not in the path. This encoder emits %20 consistently, which is always safe.
#### URL Decode
URL: https://cleanweb.tools/tools/url-encoder-decoder/decode
Spec: RFC 3986
URL decoding reverses percent-encoding: every "%XX" sequence becomes the byte with hex value XX, and UTF-8 byte sequences reassemble into their original characters. This decoder uses decodeURIComponent, which handles the full RFC 3986 encoded-character set and decodes UTF-8 multi-byte sequences correctly.
Typical decoding flow: you have a copy-pasted URL from a browser address bar where everything is percent-encoded and you want to read the actual parameters; you're inspecting an OAuth callback URL with a long state parameter and need to see what your app encoded into it; you're reading a log line with a URL and the non-ASCII characters are unreadable; you want to verify what a frontend sent by decoding the raw query string on the backend side.
When decoding fails: malformed percent sequences (%ZZ where Z isn't a hex digit), truncated sequences (% at the end with no following digits), invalid UTF-8 byte sequences that can't reassemble into characters. The decoder will throw URIError, which is a signal the input isn't valid percent-encoding. Common cause: a URL that was encoded twice (double-encoding produces %25XX instead of %XX), which you fix by running the decoder twice.
**Q: Why am I getting URIError on valid-looking input?**
A: Usually a stray % that isn't followed by two hex digits ("100%" would produce URIError on the trailing %), or an invalid UTF-8 byte sequence (%E9 alone isn't valid UTF-8, it needs continuation bytes). Trim the input to just the percent-encoded portion and try again.
**Q: What's double-encoding and how do I fix it?**
A: Double-encoding is when a URL gets percent-encoded twice, producing strings like %2520 (which is %20 with its % re-encoded as %25). The fix is to decode twice. If you run the decoder once and the output still has %XX sequences in it, decode again. Three-times encoding is rare but possible.
**Q: Should I decode + as a space?**
A: Depends on context. In query strings from HTML form submissions, + means space (application/x-www-form-urlencoded convention). In URL paths or fragments, + is a literal plus sign. decodeURIComponent treats + as literal; browsers handle the form-data form separately. If you're decoding a form submission, pre-replace + with space before decoding.
**Q: Can I decode a URL that came from an email?**
A: Yes, but emails sometimes break long URLs across lines or insert soft-wrap markers (= at end of line in quoted-printable). Remove those first. Also check if the email client already decoded some characters — pasting a half-decoded URL into this tool will fail on sequences that are already plain text.
---
## Timestamp Converter
URL: https://cleanweb.tools/tools/timestamp-converter
Tags: timestamp, unix, date, time, converter
Convert Unix timestamps to human-readable date formats and vice versa. Support for various date formats, timezones, and instant conversion. Essential for developers working with APIs and databases.
### Features
- Convert Unix timestamps to human-readable dates
- Convert dates to Unix timestamp format
- Support for multiple date formats and timezones
- View the current timestamp in real-time
### How to use
1. Enter a Unix timestamp or select a date
2. View the converted result in the other format
3. Choose your preferred date format and timezone
4. Copy the converted value to clipboard
### FAQ
**Q: Are Unix timestamps in seconds or milliseconds?**
A: Classic Unix is seconds since 1970-01-01 UTC; JavaScript's Date.now() is milliseconds. If your value is around 10 digits, it's seconds; around 13 digits, it's milliseconds. The converter auto-detects by magnitude — a value like 1745000000 is assumed to be seconds.
**Q: Why does the same timestamp show a different date in my app?**
A: Timezones. A timestamp is a single instant, but how it displays depends on the viewer's timezone. "1745000000" is 2025-04-18 17:33 UTC but 13:33 in New York and 10:33 in San Francisco. Always display in the user's local zone unless your app needs UTC explicitly.
**Q: What happens after the 2038 problem?**
A: 32-bit signed Unix timestamps overflow on 2038-01-19 at 03:14:07 UTC. Most modern systems (Linux, JS, Postgres BIGINT) already use 64-bit timestamps and aren't affected. If you're still running 32-bit embedded C code, that's the year to upgrade.
**Q: Can I convert dates before 1970?**
A: Yes — Unix timestamps go negative for dates before the epoch. -1000000000 is 1938-04-24. JavaScript's Date handles these, but some databases (older MySQL TIMESTAMP, some APIs) reject negatives. Use DATETIME or ISO-8601 strings for historical dates.
**Q: Is ISO 8601 or Unix timestamp a better database format?**
A: Unix for fast range queries, simpler indexing, and timezone-neutral storage. ISO 8601 for readability in logs and CSV exports. Modern Postgres's timestamptz stores as UTC internally but displays with timezone — the best of both worlds if your database supports it.
### Variants
#### Unix to Date
URL: https://cleanweb.tools/tools/timestamp-converter/unix-to-date
This converter takes a Unix timestamp (seconds or milliseconds since 1970-01-01 UTC) and renders it as a human-readable date in three formats simultaneously: local time (honouring your browser's timezone), UTC, and ISO 8601. The auto-detection logic looks at the number's magnitude — values around 10 digits are treated as seconds, 13 digits as milliseconds — so you can paste what you have and trust the output.
Use this direction when: a backend log line or database column gave you a bare integer and you need to know when it happened; you're debugging a JWT "exp" or "iat" claim (JWT uses seconds); you're sanity-checking a Stripe event timestamp (Stripe uses seconds in most places but milliseconds in a few newer fields — the converter handles both); you're reading event data from Unix-native tooling like `ls -l --time-style=+%s`.
The ISO 8601 output ends with "Z" when the date is in UTC, or with an offset like "+02:00" for local time in non-UTC zones. Most API specifications (RFC 3339 subset of ISO 8601) require the "Z" or explicit offset; "2026-04-23T10:00:00" without a zone is ambiguous and should be avoided in new interfaces. Copy whichever format matches your target API's expectations.
**Q: How does the converter know if my timestamp is seconds or milliseconds?**
A: It looks at the magnitude. A 10-digit number (like 1735689600) is too small to be a reasonable millisecond timestamp — it'd place the date in 1970. 13-digit numbers are treated as ms. The threshold is around 9,999,999,999. You can override by multiplying or dividing by 1000 before pasting.
**Q: What timezone does the "local" output use?**
A: Your browser's configured timezone — typically derived from the operating system. If you need a specific zone (e.g., "what is this timestamp in Tokyo"), use the ISO output as input to a dedicated timezone tool. The "UTC" output is always stable regardless of your location.
**Q: Why is the date I converted one day off?**
A: Usually a timezone confusion. A timestamp like 1735603200 is Dec 31 midnight UTC — which is Dec 30 evening in the Americas and Jan 1 morning in Asia. The local output reflects your zone; to reason about the "day" unambiguously, use UTC.
**Q: Can I convert timestamps in nanoseconds?**
A: Not directly — the converter expects seconds or milliseconds. For nanoseconds (common in Go's time.Now().UnixNano() or Prometheus metrics), divide by 1,000,000 first to get ms, then paste. You lose sub-millisecond precision but gain readable dates.
#### Date to Unix
URL: https://cleanweb.tools/tools/timestamp-converter/date-to-unix
This direction takes a date and returns the corresponding Unix timestamp — seconds and milliseconds simultaneously. The input is a browser datetime-local picker, so you can type or pick a date/time value and immediately see its epoch representation. The conversion uses JavaScript's Date constructor, which accepts ISO 8601 strings, RFC 2822 date strings, and a dozen other pragmatic formats.
Use this direction when: you're hard-coding a timestamp into a test fixture and don't want to run code to get it; you're configuring a scheduled job in a system that accepts Unix times (cron wrappers, AWS EventBridge, Cloudflare Workers Cron); you're filling a database seed file with timestamp column values; you're debugging whether a date-shaped config is getting parsed correctly by calculating what Unix time it would represent.
The datetime-local input is timezone-naive — it records the "wall clock" time in your local zone. The conversion to Unix timestamp interprets it in UTC by default. If you need to produce a timestamp for a specific other timezone ("what is 2026-06-01 09:00 Tokyo time?"), add the offset manually (Tokyo is UTC+9, subtract 9 hours) or use a dedicated timezone-aware tool.
**Q: How do I enter a specific timezone?**
A: The datetime-local input is timezone-naive and gets interpreted in your local browser zone. For an explicit timezone, paste an ISO 8601 string like "2026-04-23T10:00:00+09:00" into a full-ISO parser or manually add/subtract hours. There's no clean UI for specifying arbitrary zones here.
**Q: Why do I get different Unix timestamps for the same date in different browsers?**
A: Browser timezone detection reads from the OS. If your OS is in different zones on different devices (a travel laptop vs home desktop), you'll get different Unix times for the same wall-clock time. Always use explicit UTC or offset for values that need to match across devices.
**Q: Should I output seconds or milliseconds?**
A: Depends on the consumer. Unix CLI tools, cron, JWT, most database timestamp columns, and most Unix-era APIs use seconds. JavaScript's Date.now(), newer JSON APIs, and anything derived from JS use milliseconds. The tool shows both; copy the one your target expects.
**Q: Can I convert a date before 1970?**
A: Yes — the result is a negative Unix timestamp. "1968-01-01" is around -63,158,400 seconds. JavaScript handles negatives natively; some databases (older MySQL TIMESTAMP) reject them. For historical dates, ISO 8601 strings are more portable than negative Unix times.
#### Millisecond Timestamp
URL: https://cleanweb.tools/tools/timestamp-converter/milliseconds
Millisecond-precision Unix timestamps (the 13-digit values produced by JavaScript's Date.now()) are the default format for modern web APIs, WebSocket ping/pong, real-time event systems, and anything that needs sub-second precision without the complexity of nanosecond fields. This converter pre-fills the input with the current Date.now() value and emphasises millisecond output alongside the classic seconds representation.
The second-vs-millisecond choice matters in a few places: JavaScript (Date.now() and new Date(ms)) always uses milliseconds. Most REST APIs that accept a timestamp in a JSON body use milliseconds. Most databases that store timestamps as an integer use seconds (except where explicitly ms — some MongoDB and CouchDB setups, InfluxDB with a precision setting). Most Unix CLI tools (date +%s, cron @reboot) use seconds. When two systems disagree — a JavaScript frontend sending ms, a Python backend expecting seconds — bugs appear as 1000× or 1/1000× date drift, often misdiagnosed as timezone issues.
This variant is optimised for the JS-native case: the input starts populated with "right now in ms", the output shows ms first, and the seconds output is still there for interop. Paste any 13-digit number and get the date; pick a date and get the ms value.
**Q: Why is my API timestamp 1000× bigger than expected?**
A: Almost always a seconds/milliseconds mismatch. JavaScript produces milliseconds (13 digits); many backends assume seconds (10 digits). Divide by 1000 to convert ms → s, or multiply to go the other way. If the date lands around 1970 or 50,000 years in the future, you've got the unit wrong.
**Q: Is milliseconds precision enough for event ordering?**
A: Usually yes — two events in the same millisecond are rare in most apps. For high-frequency systems (trading, ad-bidding), add a per-process counter or use a UUID v7 which embeds a ms timestamp plus 74 random bits. For nanosecond precision, use Date.now() + performance.now() or a native API.
**Q: Do database timestamp columns store milliseconds or seconds?**
A: Depends on the database and column type. Postgres TIMESTAMP and TIMESTAMPTZ store microseconds internally. MySQL DATETIME(3) stores milliseconds; plain DATETIME is seconds. MongoDB Date is milliseconds. ALWAYS confirm by reading docs — wrong assumptions create off-by-1000 bugs.
**Q: Is Date.now() the same across devices?**
A: Close, within clock-sync error. Most devices sync via NTP within ~100 ms of real time. For events you want to compare across machines, server-side timestamps are authoritative — don't trust client clocks for anything that needs to order with other clients'.
---
## Image to Base64
URL: https://cleanweb.tools/tools/image-to-base64
Tags: image, base64, data url, embed, converter
Convert images to Base64 encoded data URLs that can be embedded directly in HTML, CSS, or JavaScript. Supports PNG, JPG, GIF, and other common image formats.
### Features
- Convert PNG, JPG, GIF, and other images to Base64
- Generate data URLs for embedding in HTML and CSS
- Preview uploaded images before conversion
- Copy the Base64 data URL to clipboard
### How to use
1. Upload an image file using the file picker or drag and drop
2. View the image preview and file details
3. Copy the Base64 data URL from the output
4. Paste the data URL directly in your HTML or CSS
### FAQ
**Q: When should I inline an image instead of linking to it?**
A: Tiny icons under 2 KB, or a single above-the-fold hero you don't want a separate HTTP round-trip for. Past around 10 KB, the Base64 bloat (33% expansion) plus the fact that inline images can't be cached separately starts hurting page load — link them instead.
**Q: Does inlining affect caching?**
A: Yes — inlined images cache with their host HTML or CSS file, not separately. If the image changes but the page doesn't, the browser still has to re-download it with the page. Good for truly one-off assets, bad for anything reused across many pages.
**Q: Which image format should I base64 — PNG, JPG, or SVG?**
A: SVG whenever possible — it's text, Base64 encoding costs less (since the source is already UTF-8), and it scales. For raster, prefer WebP or AVIF when browser support allows, fall back to JPG for photos, PNG for anything needing transparency.
**Q: Is my image uploaded to a server?**
A: No — the encoding runs in the browser via FileReader and the file never leaves your machine. This matters for screenshots with sensitive data or unreleased mockups. The resulting data URL is yours to paste into your own code.
**Q: Can I decode a data URL back into an image?**
A: Yes — paste the data URL (the data:image/... string) into any decoder, or save it to a file renamed to .png/.jpg. Most browsers also handle pasting a data URL directly into the address bar and will render the image.
---
## JSON to CSV Converter
URL: https://cleanweb.tools/tools/json-to-csv
Tags: json, csv, converter, data, spreadsheet
Transform JSON arrays into CSV spreadsheet format or convert CSV files back to JSON. Handle nested objects, customize delimiters, and download results. Perfect for data migration and analysis.
### Features
- Convert JSON arrays to CSV spreadsheet format
- Convert CSV data back to JSON format
- Handle nested objects and complex data structures
- Download converted data as a file
### How to use
1. Paste your JSON or CSV data into the input field
2. Select the conversion direction (JSON to CSV or CSV to JSON)
3. View the converted output instantly
4. Copy or download the result
### FAQ
**Q: How does the converter handle nested JSON?**
A: Flattened by default using dot notation: {"user": {"name": "Ada"}} becomes a column "user.name". Arrays of scalars are joined by semicolons ("a;b;c"), arrays of objects become repeated rows. If your data is deeply nested, preprocess it before converting — CSV is fundamentally flat.
**Q: Why does Excel mangle my CSV?**
A: Usually because Excel interprets comma-separated cells per your locale — in European locales, Excel expects semicolons as the delimiter. Either export with semicolons, prepend the file with sep=,\n (Excel respects this hint), or use Excel's "Data > From Text" workflow rather than double-clicking.
**Q: How do I handle commas inside values?**
A: They get wrapped in double quotes: "Paris, France". The tool does this automatically per RFC 4180. If you're hand-writing a CSV, remember that embedded quotes get doubled ("She said ""hi"""), not escaped with a backslash.
**Q: Is my data sent anywhere during conversion?**
A: No — everything runs in your browser. That matters for customer exports, financial data, and anything with PII where sending the file to a random online converter would be a compliance issue. Paste, convert, download, move on.
**Q: Should I use JSON or CSV for bulk data exchange?**
A: JSON for structured data, nested objects, or anything that'll be read by code. CSV for flat, column-oriented data that'll be opened in a spreadsheet or loaded into a relational database. CSV is smaller on the wire; JSON is more self-describing. Pick based on the consumer.
### Variants
#### JSON → CSV
URL: https://cleanweb.tools/tools/json-to-csv/json-to-csv
Spec: RFC 4180
JSON-to-CSV conversion takes an array of JSON objects and produces a header row plus one data row per object. The first object's keys become the column headers; each subsequent row is the same key order. Values containing commas, quotes, or newlines get wrapped in double quotes per RFC 4180, with embedded quotes doubled. Nested objects are flattened with dot notation — `{"user": {"name": "Ada"}}` becomes a column named `user.name`. Arrays of scalars are joined by semicolons inside the cell.
Typical use cases: exporting a database query result (API returns JSON, user wants Excel) without writing code; prepping analytics data for a business user's spreadsheet; flattening a webhook payload into a format that loads cleanly into a BI tool; converting a fixture file in your test suite from JSON to CSV for a non-technical teammate to edit.
Gotchas: the JSON must be a top-level array, not an object containing an array (wrap the array directly or extract it first). If objects have different keys, only the first object's keys become columns — missing values are left blank. Arrays of objects nested inside fields produce JSON-encoded cells rather than separate rows; if that's not what you want, flatten manually in code before pasting.
**Q: How does the converter handle nested JSON?**
A: Flattened with dot notation: `{"user": {"name": "Ada", "email": "ada@example.com"}}` becomes columns `user.name` and `user.email`. Arrays of scalars are joined by semicolons in the cell. Arrays of objects become JSON-encoded cells — flatten those manually if you want separate rows.
**Q: What if my objects have different keys?**
A: Only the first object's keys become column headers. Keys that appear in later objects but not the first are dropped. Keys from the first object missing in later objects produce empty cells. If your data has inconsistent shape, normalise to a superset of keys before converting.
**Q: Why does my output have quotes around every cell?**
A: Cells get quoted only when they contain commas, double quotes, or newlines (per RFC 4180). If you're seeing quotes on every cell, your data probably has a comma or newline in each value. Check the source — some numeric columns get exported as "1,000" strings from Excel.
**Q: Can I use a different delimiter like tab or semicolon?**
A: The current tool defaults to comma. For tab-separated (TSV) or semicolon-separated (European Excel default), post-process the output — JSON → CSV → find-and-replace , with \t or ;. Regional Excel versions assume semicolons, so that's a common target.
#### CSV → JSON
URL: https://cleanweb.tools/tools/json-to-csv/csv-to-json
Spec: RFC 4180
CSV-to-JSON conversion takes a CSV with a header row and produces an array of objects where each row becomes one object. Column headers become object keys; values become object values. The parser handles RFC 4180 quoting (commas inside quoted cells, double-quote escaping, multi-line quoted values), trims whitespace, and preserves the column order via JavaScript object-key insertion order.
Typical use cases: importing a spreadsheet into a codebase as a fixture; converting Excel export data for a REST API that expects JSON; loading a lookup table into JavaScript without having to hand-transform; prepping data for a JSON-based ETL pipeline from legacy CSV sources.
By default all values are strings — "42" stays as "42", "true" stays as "true". This is deliberately lossless; coercing "42" to a number silently changes the type of a ZIP code column (where "01234" would become 1234) and can't be reversed. If your downstream code needs typed values, post-process each column explicitly — cast ZIP codes to string, parse prices to float, parse dates to Date. The manual step is short, the silent-coercion bugs aren't.
**Q: Why are my numbers kept as strings?**
A: Deliberate — auto-coercing "42" to a number would corrupt ZIP codes ("01234" → 1234), phone numbers, and any fields where leading zeros matter. The converter returns every value as a string; you cast in your downstream code where you know each column's intended type.
**Q: What does the converter do with empty cells?**
A: Empty string. `name,email\nAda,` produces `[{"name": "Ada", "email": ""}]`, not null. If you need nulls for absent values, post-process: `data.map(r => ({ ...r, email: r.email || null }))`.
**Q: How does it handle multi-line values?**
A: RFC 4180 allows newlines inside double-quoted cells. The parser recognises `"line one\nline two"` as a single field. Make sure your source actually emits quoted multi-lines — some CSV exporters break the spec and use \r\n as a field separator inside unquoted text, which ruins parsing.
**Q: Will the output preserve column order?**
A: Yes — JavaScript objects preserve insertion order, so the JSON stringified output lists keys in the same order as the CSV's header row. JSON specs don't require this, but every mainstream parser has behaved this way for years. Safe to rely on for display and round-tripping.
---