[{"data":1,"prerenderedAt":723},["ShallowReactive",2],{"guide-url-encoding-special-chars":3},{"id":4,"title":5,"body":6,"date":715,"description":716,"extension":717,"meta":718,"navigation":438,"path":719,"readingTime":463,"seo":720,"stem":721,"__hash__":722},"guides\u002Fguides\u002Furl-encoding-special-chars.md","URL Encoding Special Characters Guide",{"type":7,"value":8,"toc":700},"minimark",[9,18,23,28,31,203,207,210,363,367,370,393,480,500,504,507,515,518,522,526,529,588,604,608,614,620,624,633,639,642,646,683,687,696],[10,11,12,13,17],"p",{},"URLs can only contain a limited set of ASCII characters — letters, digits, and a few reserved punctuation marks. Everything else must be percent-encoded: replaced by a ",[14,15,16],"code",{},"%"," sign followed by two hexadecimal digits. Knowing which characters require encoding and when is essential for building correct links, query strings, and API requests.",[19,20,22],"h2",{"id":21},"characters-that-require-encoding","Characters That Require Encoding",[24,25,27],"h3",{"id":26},"reserved-characters","Reserved Characters",[10,29,30],{},"Reserved characters have special meaning in URL syntax. When they appear as data (not as delimiters), they must be encoded.",[32,33,34,50],"table",{},[35,36,37],"thead",{},[38,39,40,44,47],"tr",{},[41,42,43],"th",{},"Character",[41,45,46],{},"Encoded",[41,48,49],{},"Purpose in URL Syntax",[51,52,53,69,84,99,114,129,144,159,174,189],"tbody",{},[38,54,55,61,66],{},[56,57,58],"td",{},[14,59,60],{},"&",[56,62,63],{},[14,64,65],{},"%26",[56,67,68],{},"Query parameter separator",[38,70,71,76,81],{},[56,72,73],{},[14,74,75],{},"=",[56,77,78],{},[14,79,80],{},"%3D",[56,82,83],{},"Key-value assignment",[38,85,86,91,96],{},[56,87,88],{},[14,89,90],{},"?",[56,92,93],{},[14,94,95],{},"%3F",[56,97,98],{},"Query string start",[38,100,101,106,111],{},[56,102,103],{},[14,104,105],{},"#",[56,107,108],{},[14,109,110],{},"%23",[56,112,113],{},"Fragment identifier",[38,115,116,121,126],{},[56,117,118],{},[14,119,120],{},"\u002F",[56,122,123],{},[14,124,125],{},"%2F",[56,127,128],{},"Path separator",[38,130,131,136,141],{},[56,132,133],{},[14,134,135],{},":",[56,137,138],{},[14,139,140],{},"%3A",[56,142,143],{},"Scheme\u002Fport separator",[38,145,146,151,156],{},[56,147,148],{},[14,149,150],{},";",[56,152,153],{},[14,154,155],{},"%3B",[56,157,158],{},"Parameter separator",[38,160,161,166,171],{},[56,162,163],{},[14,164,165],{},"@",[56,167,168],{},[14,169,170],{},"%40",[56,172,173],{},"Authority delimiter",[38,175,176,181,186],{},[56,177,178],{},[14,179,180],{},"+",[56,182,183],{},[14,184,185],{},"%2B",[56,187,188],{},"Space (form encoding)",[38,190,191,195,200],{},[56,192,193],{},[14,194,16],{},[56,196,197],{},[14,198,199],{},"%25",[56,201,202],{},"Encoding prefix itself",[24,204,206],{"id":205},"unsafe-and-non-ascii-characters","Unsafe and Non-ASCII Characters",[10,208,209],{},"Characters that have no defined role in URLs, or that may be modified by transport layers, should always be encoded.",[32,211,212,223],{},[35,213,214],{},[38,215,216,218,220],{},[41,217,43],{},[41,219,46],{},[41,221,222],{},"Reason",[51,224,225,241,256,270,285,307,322,334,349],{},[38,226,227,230,238],{},[56,228,229],{},"Space",[56,231,232,235,236],{},[14,233,234],{},"%20"," or ",[14,237,180],{},[56,239,240],{},"Not allowed in URLs",[38,242,243,248,253],{},[56,244,245],{},[14,246,247],{},"\u003C",[56,249,250],{},[14,251,252],{},"%3C",[56,254,255],{},"HTML injection risk",[38,257,258,263,268],{},[56,259,260],{},[14,261,262],{},">",[56,264,265],{},[14,266,267],{},"%3E",[56,269,255],{},[38,271,272,277,282],{},[56,273,274],{},[14,275,276],{},"\"",[56,278,279],{},[14,280,281],{},"%22",[56,283,284],{},"Delimiter in HTML attributes",[38,286,287,296,304],{},[56,288,289,292,293],{},[14,290,291],{},"{"," ",[14,294,295],{},"}",[56,297,298,292,301],{},[14,299,300],{},"%7B",[14,302,303],{},"%7D",[56,305,306],{},"Unsafe, often filtered",[38,308,309,314,319],{},[56,310,311],{},[14,312,313],{},"\\",[56,315,316],{},[14,317,318],{},"%5C",[56,320,321],{},"Path manipulation risk",[38,323,324,327,329],{},[56,325,326],{},"`",[56,328,326],{},[56,330,331],{},[14,332,333],{},"%7C",[38,335,336,341,346],{},[56,337,338],{},[14,339,340],{},"é",[56,342,343],{},[14,344,345],{},"%C3%A9",[56,347,348],{},"Non-ASCII (UTF-8 encoded)",[38,350,351,356,361],{},[56,352,353],{},[14,354,355],{},"中",[56,357,358],{},[14,359,360],{},"%E4%B8%AD",[56,362,348],{},[24,364,366],{"id":365},"space-encoding-20-vs","Space Encoding: %20 vs +",[10,368,369],{},"Spaces in URLs have two encodings, and the difference matters:",[371,372,373,382],"ul",{},[374,375,376,381],"li",{},[377,378,379],"strong",{},[14,380,234],{}," — The standard percent-encoding defined by RFC 3986. Used in path segments and any part of the URL.",[374,383,384,388,389,392],{},[377,385,386],{},[14,387,180],{}," — Defined by the ",[14,390,391],{},"application\u002Fx-www-form-urlencoded"," media type (HTML form submissions). Only valid in query strings.",[394,395,400],"pre",{"className":396,"code":397,"language":398,"meta":399,"style":399},"language-javascript shiki shiki-themes github-light github-dark","\u002F\u002F Correct: encode path spaces as %20\nconst path = '\u002Ffiles\u002Fmy%20document.pdf';\n\n\u002F\u002F Correct: encode query spaces as + (form-style) or %20\nconst query = 'name=John+Doe';\nconst query2 = 'name=John%20Doe';  \u002F\u002F Also valid in query strings\n","javascript","",[14,401,402,411,433,440,446,461],{"__ignoreMap":399},[403,404,407],"span",{"class":405,"line":406},"line",1,[403,408,410],{"class":409},"sJ8bj","\u002F\u002F Correct: encode path spaces as %20\n",[403,412,414,418,422,425,429],{"class":405,"line":413},2,[403,415,417],{"class":416},"szBVR","const",[403,419,421],{"class":420},"sj4cs"," path",[403,423,424],{"class":416}," =",[403,426,428],{"class":427},"sZZnC"," '\u002Ffiles\u002Fmy%20document.pdf'",[403,430,432],{"class":431},"sVt8B",";\n",[403,434,436],{"class":405,"line":435},3,[403,437,439],{"emptyLinePlaceholder":438},true,"\n",[403,441,443],{"class":405,"line":442},4,[403,444,445],{"class":409},"\u002F\u002F Correct: encode query spaces as + (form-style) or %20\n",[403,447,449,451,454,456,459],{"class":405,"line":448},5,[403,450,417],{"class":416},[403,452,453],{"class":420}," query",[403,455,424],{"class":416},[403,457,458],{"class":427}," 'name=John+Doe'",[403,460,432],{"class":431},[403,462,464,466,469,471,474,477],{"class":405,"line":463},6,[403,465,417],{"class":416},[403,467,468],{"class":420}," query2",[403,470,424],{"class":416},[403,472,473],{"class":427}," 'name=John%20Doe'",[403,475,476],{"class":431},";  ",[403,478,479],{"class":409},"\u002F\u002F Also valid in query strings\n",[10,481,482,483,486,487,489,490,492,493,496,497,499],{},"Mixing these up causes bugs. Decoding ",[14,484,485],{},"my+document.pdf"," as a path produces ",[14,488,485],{}," (the ",[14,491,180],{}," is literal), while decoding it as form data produces ",[14,494,495],{},"my document.pdf",". Always use ",[14,498,234],{}," for paths and either form for queries, but decode consistently.",[19,501,503],{"id":502},"unicode-encoding","Unicode Encoding",[10,505,506],{},"Non-ASCII characters are encoded as their UTF-8 byte sequence, with each byte percent-encoded:",[394,508,513],{"className":509,"code":511,"language":512},[510],"language-text","Character:  é\nUnicode:    U+00E9\nUTF-8:      0xC3 0xA9\nEncoded:    %C3%A9\n\nCharacter:  中\nUnicode:    U+4E2D\nUTF-8:      0xE4 0xB8 0xAD\nEncoded:    %E4%B8%AD\n\nCharacter:  😊\nUnicode:    U+1F60A\nUTF-8:      0xF0 0x9F 0x98 0x8A\nEncoded:    %F0%9F%98%8A\n","text",[14,514,511],{"__ignoreMap":399},[10,516,517],{},"Modern browsers display Unicode characters in the address bar for readability, but the underlying bytes are always percent-encoded. You can verify this by copying a URL with non-ASCII characters and pasting it into a plain text editor.",[19,519,521],{"id":520},"common-pitfalls","Common Pitfalls",[24,523,525],{"id":524},"double-encoding","Double Encoding",[10,527,528],{},"Encoding an already-encoded string produces double-encoded output that breaks the URL:",[394,530,532],{"className":396,"code":531,"language":398,"meta":399,"style":399},"const query = 'a=b&c=d';\nconst encoded = encodeURIComponent(query);     \u002F\u002F a%3Db%26c%3Dd\nconst doubleEncoded = encodeURIComponent(encoded); \u002F\u002F a%253Db%2526c%253Dd\n\u002F\u002F Decoding double-encoded string: a%3Db%26c%3Dd (still encoded!)\n",[14,533,534,547,566,583],{"__ignoreMap":399},[403,535,536,538,540,542,545],{"class":405,"line":406},[403,537,417],{"class":416},[403,539,453],{"class":420},[403,541,424],{"class":416},[403,543,544],{"class":427}," 'a=b&c=d'",[403,546,432],{"class":431},[403,548,549,551,554,556,560,563],{"class":405,"line":413},[403,550,417],{"class":416},[403,552,553],{"class":420}," encoded",[403,555,424],{"class":416},[403,557,559],{"class":558},"sScJk"," encodeURIComponent",[403,561,562],{"class":431},"(query);     ",[403,564,565],{"class":409},"\u002F\u002F a%3Db%26c%3Dd\n",[403,567,568,570,573,575,577,580],{"class":405,"line":435},[403,569,417],{"class":416},[403,571,572],{"class":420}," doubleEncoded",[403,574,424],{"class":416},[403,576,559],{"class":558},[403,578,579],{"class":431},"(encoded); ",[403,581,582],{"class":409},"\u002F\u002F a%253Db%2526c%253Dd\n",[403,584,585],{"class":405,"line":442},[403,586,587],{"class":409},"\u002F\u002F Decoding double-encoded string: a%3Db%26c%3Dd (still encoded!)\n",[10,589,590,591,594,595,597,598,600,601,603],{},"Never encode a full URL with ",[14,592,593],{},"encodeURIComponent",". It encodes the ",[14,596,135],{},", ",[14,599,120],{},", and ",[14,602,90],{}," that are part of the URL structure. Use it only on individual parameter values.",[24,605,607],{"id":606},"ampersand-in-parameter-values","Ampersand in Parameter Values",[10,609,610,611,613],{},"An unencoded ",[14,612,60],{}," in a query parameter value truncates the value:",[394,615,618],{"className":616,"code":617,"language":512},[510],"Wrong:  ?redirect=https:\u002F\u002Fexample.com?a=1&b=2\n       → redirect = \"https:\u002F\u002Fexample.com?a=1\", b = \"2\" (separate param)\n\nRight:  ?redirect=https%3A%2F%2Fexample.com%3Fa%3D1%26b%3D2\n       → redirect = \"https:\u002F\u002Fexample.com?a=1&b=2\"\n",[14,619,617],{"__ignoreMap":399},[24,621,623],{"id":622},"slash-encoding-in-paths","Slash Encoding in Paths",[10,625,626,627,629,630,632],{},"Some web frameworks decode ",[14,628,125],{}," in path segments, while others treat it as a literal ",[14,631,125],{},". This causes routing discrepancies:",[394,634,637],{"className":635,"code":636,"language":512},[510],"\u002Ffiles\u002Fpath%2Fto%2Ffile → May route to \u002Ffiles\u002Fpath\u002Fto\u002Ffile OR \u002Ffiles\u002Fpath%2Fto%2Ffile\n",[14,638,636],{"__ignoreMap":399},[10,640,641],{},"If slashes in a path parameter are meaningful data, test your framework's behavior explicitly.",[19,643,645],{"id":644},"key-takeaways","Key Takeaways",[371,647,648,662,671,674,680],{},[374,649,650,651,597,653,597,655,597,657,597,659,661],{},"Reserved characters (",[14,652,60],{},[14,654,75],{},[14,656,90],{},[14,658,105],{},[14,660,120],{},") must be encoded when used as data, not delimiters.",[374,663,664,665,667,668,670],{},"Use ",[14,666,234],{}," for spaces in paths; ",[14,669,180],{}," is only valid in form-encoded query strings.",[374,672,673],{},"Unicode characters are percent-encoded as their UTF-8 byte sequences.",[374,675,676,677,679],{},"Never ",[14,678,593],{}," a full URL — only encode individual query values.",[374,681,682],{},"Double encoding is a common source of broken links; always encode exactly once.",[19,684,686],{"id":685},"try-it-yourself","Try It Yourself",[10,688,689,690,695],{},"Need to encode or decode a URL? Paste it into the ",[691,692,694],"a",{"href":693},"\u002Ftools\u002Furl-encoder","URL Encoder"," to see each component properly percent-encoded, or decode an encoded URL to inspect its original form.",[697,698,699],"style",{},"html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}",{"title":399,"searchDepth":413,"depth":413,"links":701},[702,707,708,713,714],{"id":21,"depth":413,"text":22,"children":703},[704,705,706],{"id":26,"depth":435,"text":27},{"id":205,"depth":435,"text":206},{"id":365,"depth":435,"text":366},{"id":502,"depth":413,"text":503},{"id":520,"depth":413,"text":521,"children":709},[710,711,712],{"id":524,"depth":435,"text":525},{"id":606,"depth":435,"text":607},{"id":622,"depth":435,"text":623},{"id":644,"depth":413,"text":645},{"id":685,"depth":413,"text":686},"2026-05-28","Complete reference for encoding ampersands, spaces, slashes, and Unicode in URLs.","md",{"immutable":438},"\u002Fguides\u002Furl-encoding-special-chars",{"title":5,"description":716},"guides\u002Furl-encoding-special-chars","skASc5zzXNRWGs-loEeTmrY9F6hJ_pJG3XqyJSHLcFE",1780401337913]