A slash can separate two parts of a website address, or it can be data inside one part. Percent-encoding helps preserve that distinction. If a system decodes an entire path and then splits it at every slash, data that originally belonged inside one component can become a new routing boundary.
The short answer is to keep the representation and the processing order explicit. First identify the relevant structure under the chosen URL and application rules. Decode data at the stage those rules require, and preserve the resulting component boundaries. A displayed address, a parsed URL and an application’s route arguments are related records, not interchangeable strings.
This guide uses original, fictional catalogue paths and two deliberately simplified processing pipelines. They explain a failure mechanism; they are not a replacement URL parser or a claim about how any particular server is configured.
eduKateSG · Websites
Find your next learning step
Distinguish encoded data from structural separators before following a route. Follow the worked sequence or choose the route that locates the first uncertain connection.
ROUTE 1 · CHAPTERS 1–5
Name the representation
Identify the written path, its component data and the exact routing contract.
ROUTE 2 · CHAPTERS 6–10
Follow the decoding order
Follow two processing orders and locate where an encoded separator changes structure.
ROUTE 3 · CHAPTERS 11–15
Check component boundaries
Check format-specific plus signs, empty components, rejection and decoding layers.
ROUTE 4 · CHAPTERS 16–21
Audit and transfer
Preserve route identity through canonicalisation, caches and two changed examples.
ROUTE 5 · CHAPTERS 22–26
Practise and continue
Repair an explanation, choose practice and follow the relevant website guides.
Chapter contents
Name the representation · Chapters 1–5
1. Begin with the route the application intends
2. Separate the written path from decoded component data
3. Understand what percent-encoding represents
Follow the decoding order · Chapters 6–10
6. Explain the noncommuting operations
7. Distinguish encoded delimiters from unreserved characters
8. Decode a represented percent sign only at its intended layer
Check component boundaries · Chapters 11–15
11. Recognise that plus has format-specific meaning
12. Preserve empty components when the contract needs them
13. Distinguish an explicit rejection from a wrong destination
14. Track the value across several processing layers
15. Avoid rejoining a structured list without an encoding rule
Audit and transfer · Chapters 16–21
16. Keep canonicalisation separate from arbitrary equivalence
17. Do not infer route correctness from cache behaviour
18. Try a changed catalogue path
19. Check a changed form value in its own format
Practise and continue · Chapters 22–26
22. Repair a misleading explanation
24. Questions about decoding and routes
CHAPTER 1 OF 26 · Name the representation
1. Begin with the route the application intends
Imagine a fictional catalogue whose route consists of two named components: a collection and an item identifier. The collection is catalog, and one item identifier is the three-character string A/B. Within that identifier, the slash is data.
The application has chosen a route contract that can represent such an identifier as one component. Whether a real framework permits this, rejects it or uses another route design depends on its documented behaviour. Our exercise supplies the contract rather than assuming it from the appearance of a link.
A route contract answers a practical question: which structured values should reach the intended handler? Here, the intended values are collection catalog and item A/B. That is different from three path components catalog, A and B.
The Websites subject guide connects clear navigation with dependable service. This narrower guide follows the representation boundary between an address and the values an application interprets. The page can look ordinary while that boundary determines which resource the request actually identifies.
CHAPTER 2 OF 26 · Name the representation
2. Separate the written path from decoded component data
The fictional written path is /catalog/A%2FB. Its literal slash characters occur before catalog and before A%2FB. The characters %2F represent an encoded slash byte; they are not a literal slash in that written representation.
Under our supplied route contract, splitting at the structural slashes produces the component strings catalog and A%2FB. Decoding the second component then produces the item identifier A/B while retaining its identity as one component.
Keep the brackets around the result conceptually: a list containing catalog and A/B is not the same object as one undifferentiated string catalog/A/B. If the components are immediately joined and reparsed without suitable encoding, their recovered boundary can be lost again.
A useful first exercise asks learners to mark literal separators with vertical pencil strokes and encoded data with a different annotation. The aim is not to memorise one special path. It is to recognise which representation is being inspected and whether a transformation preserves the structure that the next stage expects.
CHAPTER 3 OF 26 · Name the representation
3. Understand what percent-encoding represents
A percent-encoded byte is written as a percent sign followed by two hexadecimal digits. In the examples here, %2F represents the ASCII slash byte, %25 represents a percent sign and %20 represents a space.
Percent-decoding bytes and interpreting those bytes as text are distinct operations. Non-ASCII text can involve several bytes under a stated character encoding. A rule that treats every encoded byte as one complete visible character can therefore misread text as well as routing structure.
For an original text example, the written component Caf%C3%A9 represents Café when its bytes are decoded as UTF-8. The two encoded bytes C3 and A9 jointly represent the final letter; they are not two independent visible letters. A component ledger can retain the written form, the byte sequence and the resulting text without pretending those are the same layer. If the bytes are interpreted under a different character encoding, the visible result can differ even while the slash boundaries stay unchanged. This adds a text-decoding question to the route question, which is why a successful split alone cannot establish the complete identifier value.
RFC 3986 defines the generic URI distinction between reserved delimiters and data. Its sections 2.2–2.4 explain why component parsing and decoding order matter, while the WHATWG URL Standard specifies contemporary URL parsing and related APIs.
These sources describe different scopes. Our small ASCII examples isolate one component-order question. Real implementation should use the appropriate maintained parser and application documentation, including its rules for malformed input, text decoding and accepted path values. The exercise does not establish those rules for a deployed service.
CHAPTER 4 OF 26 · Name the representation
4. Compare two explicit processing pipelines
Call the first teaching pipeline split-then-decode. It takes the already identified written path, splits its literal structural separators and decodes each resulting component once. Its output is a list of component values.
Call the second pipeline decode-then-split. It decodes the whole written path first and subsequently splits the resulting text at every slash. Its output can contain boundaries created from decoded data.
For /catalog/A%2FB, the first produces two meaningful components: catalog and A/B. The second first creates /catalog/A/B, then produces three components: catalog, A and B. The two lists differ in length and meaning.
The comparison deliberately holds the input constant and changes only the operation order. It does not claim every real framework follows one of these exact toy pipelines. Some retain encoded slashes, some reject them and some decode at several layers under specific rules. The useful question is which structured values survive the actual chain, rather than whether a system uses a familiar function name somewhere within it.
A ledger makes each intermediate representation inspectable. The following paths belong to the fictional exercise and should not be treated as live destinations or production test requests.
| Written path | Split-then-decode component values | Decode-then-split component values |
|---|---|---|
| /catalog/AB | catalog; AB | catalog; AB |
| /catalog/A%2FB | catalog; A/B | catalog; A; B |
| /catalog/A%252FB | catalog; A%2FB | catalog; A%2FB |
| /catalog/A%7EB | catalog; A~B | catalog; A~B |
The plain identifier AB gives agreement, so a test using only simple letters would not reveal the order difference. A%2FB exposes it. The doubly represented percent example prepares a separate question about repeated decoding; one decoding pass does not turn %252F directly into a slash.
Read the ledger as a comparison of stipulated functions. It is not an assertion that all four written forms are accepted, equivalent or routed this way by a real website. Those claims would require the actual parser, route contract and application result to be checked.
Two operations commute when changing their order leaves the relevant result unchanged. Here, splitting and decoding do not generally commute because decoding can introduce the character that splitting uses as a boundary.
For a string without encoded slashes, the two toy pipelines may agree. Agreement on that subset does not establish agreement for every permitted identifier. The counterexample is enough to disprove the universal claim.
Notice that the output types help explain the issue. Splitting produces a list. Componentwise decoding maps each list element to a value without intentionally changing the number of list elements. Decoding before splitting transforms the text from which the list structure will later be inferred.
This is a transferable programming habit: identify whether a transformation acts on a structured object or on its serialised text. The same visible characters can play different roles at those layers. A correct local text transformation can still be placed at a stage where its output is interpreted under an unintended grammar. Recording types and boundaries often clarifies the problem more quickly than adding another string replacement.
CHAPTER 7 OF 26 · Follow the decoding order
7. Distinguish encoded delimiters from unreserved characters
Not every percent-encoded byte raises the same structural question. In the generic URI framework, letters, digits, hyphen, period, underscore and tilde belong to the unreserved set. A normaliser can treat their encoded forms differently from encoded reserved delimiters.
For example, A%7EB decodes to A~B without introducing a slash boundary. The teaching pipelines therefore agree for that component. This limited agreement should not be extended to %2F merely because both forms begin with a percent sign.
The distinction is semantic: what role can the decoded character play under the relevant grammar? A rule saying decode every escape because it improves readability ignores that role. A rule saying no encoding can ever be normalised is too broad in the other direction.
When checking an implementation, separate the classes of input instead of collecting one undifferentiated set of encoded strings. Include ordinary data, encoded unreserved characters and permitted encoded delimiters under the actual route contract. The expected outcome may be a preserved value or an explicit rejection; it should be chosen from documented semantics rather than guessed from visual similarity.
CHAPTER 8 OF 26 · Follow the decoding order
8. Decode a represented percent sign only at its intended layer
In /catalog/A%252FB, a single percent-decoding pass changes %25 into a percent sign. The resulting item value is A%2FB. It still contains the literal characters percent, 2 and F as data at that stage.
A second decoding pass would turn that sequence into A/B. It has changed the value again. If a later stage then splits the decoded value, it can also change the number of apparent components.
This example does not prescribe a universal number of transformations for every nested format. A system can legitimately contain an explicitly encoded value inside another documented format. Each layer must identify what representation it consumes and what it produces.
The error is an undocumented repeated interpretation of a value as though it were still the original encoded text. Give stages names that reflect their inputs, and retain a trace showing which layer has already been decoded. A successful function call establishes that a transformation ran; it does not establish that the transformation was appropriate for the representation supplied to it.
CHAPTER 9 OF 26 · Follow the decoding order
9. Do not let display formatting become route rewriting
A browser’s address display, a copied address and an application log may present related information differently. A user-friendly display can show readable characters while the underlying URL record retains an encoded representation.
A designer should therefore separate the task of explaining a link from the task of constructing its destination. Translating the visible label does not authorise changing the address. Likewise, making an address easier to read should not silently alter the structured values sent to the application.
The existing guide to internationalised domains, URLs and email develops display, identifier and delivery boundaries. The companion on preserving web identity across languages provides another route into component-aware handling.
For a classroom check, keep three columns: what the reader sees, what is copied and which component values the stipulated application receives. The values need not have identical surface text, but their relationship should be deliberate and testable. A tidy display alone does not establish the destination.
CHAPTER 10 OF 26 · Follow the decoding order
10. Keep query and fragment boundaries outside path data
A URL can contain a path, query and fragment with different roles. Identifying those outer components is a separate step from interpreting a path’s internal segments.
Consider a fictional path component whose data contains a question mark, represented as %3F. If a whole-address decoding step introduces a literal question mark before outer components are identified, a later parser can mistake data for the start of a query. The structural mistake is related to the slash example, but occurs at another grammar boundary.
Similarly, a fragment delimiter belongs to the URL structure, while an encoded character within component data does not automatically become an instruction to select a document section. The exact behaviour depends on the applicable parsing and application rules.
The existing article on relative links when a base URL changes explains reference resolution. It deliberately leaves more involved encoding cases for separate investigation. Keep the two questions distinct: resolving a reference against a base determines an address under a URL model; interpreting that address through a route contract determines which application values are intended.
CHAPTER 11 OF 26 · Check component boundaries
11. Recognise that plus has format-specific meaning
The character plus is not a universal synonym for a space. The WHATWG application/x-www-form-urlencoded parser gives plus a specific role when interpreting that format’s name–value data.
In that format, a value written as A+B represents A followed by a space and B, while A%2BB represents A+B with a literal plus. The plus-to-space step and percent-decoding step have an order defined by the format.
Do not copy that rule indiscriminately into path handling. A fictional path identifier A+B can legitimately contain a plus under a route contract that treats it as data. Whether an application accepts that identifier is a separate question from how form data is decoded.
A useful test asks which format the string belongs to before interpreting it. The presence of a percent sign or plus does not identify the format by itself. The content type, API contract and parsing stage supply that context. Treating every address-like string as form data can replace one set of values with another while leaving the output superficially readable.
CHAPTER 12 OF 26 · Check component boundaries
12. Preserve empty components when the contract needs them
Splitting rules can also change structure by discarding empty strings. A toy path /catalog//A contains an empty segment between two slashes. A rule that removes every empty segment produces a different list from a rule that preserves internal empty segments.
Our earlier catalogue examples ignored the single leading slash as a path marker. That convention does not justify silently removing empty components anywhere else. State how the supplied route contract treats a trailing separator, repeated separators and an empty identifier.
A real application may deliberately normalise or reject some of these forms. The educational point is to document the decision. Do not present a lossy convenience operation as though it were a neutral consequence of splitting.
When writing a ledger, show empty components explicitly with a label such as empty rather than leaving an ambiguous blank. Then compare the resulting list with the expected route shape. This catches a different failure from percent-decoding order and helps a learner see that preserving component boundaries includes preserving the absence of data where the grammar regards that absence as meaningful.
CHAPTER 13 OF 26 · Check component boundaries
13. Distinguish an explicit rejection from a wrong destination
A system can respond to a disallowed encoded separator by rejecting the request. That can be consistent with its documented route contract. It differs from accepting the address and silently interpreting its data as additional components.
The expected result of a test should therefore include the relevant permitted outcome. For one application, an encoded slash may be valid identifier data. For another, identifiers may exclude slashes entirely. A comparison that labels either behaviour wrong without checking the contract has skipped the central evidence.
Keep the test question narrow: did this representation reach the intended handler with the intended values, or did the system perform the specified rejection? A status code alone may not answer which values were interpreted along the way.
For a student exercise, use an invented parser trace rather than probing an unfamiliar live service. Compare the trace with the supplied contract and locate the first departure. This teaches representation reasoning without pretending the classroom pipelines are complete security controls or implementation instructions for a real infrastructure stack.
CHAPTER 14 OF 26 · Check component boundaries
14. Track the value across several processing layers
A request may pass through a client, an intermediary, a server and an application framework before reaching a handler. Each stage can record or transform an address. A correct check at one stage does not establish that later stages preserve the same component interpretation.
For the fictional catalogue, imagine the first stage records /catalog/A%252FB and decodes the item once to A%2FB. A later stage, unaware that it has received a decoded component value, decodes again to A/B. The final value differs from the contract’s single-decoded item.
This is an original trace showing a possible disagreement, not a report of an actual vulnerability. A real investigation needs the actual stages, configuration and authorised evidence.
A helpful ledger records each stage’s input representation, transformation, output type and intended responsibility. Include stages that reject or preserve the input as well as those that change it. The trace should make it possible to point to the first unexpected interpretation instead of blaming the final page simply because that is where the reader noticed the problem.
CHAPTER 15 OF 26 · Check component boundaries
15. Avoid rejoining a structured list without an encoding rule
Suppose the application has correctly obtained the two values catalog and A/B. It later needs to construct a new written path. Joining the decoded values with a bare slash creates /catalog/A/B, which no longer visibly distinguishes the identifier’s slash from the separator.
A construction routine needs the appropriate component-encoding contract. Under our exercise, encoding the item data restores A%2FB as one written component, and the reconstructed path is /catalog/A%2FB.
This round trip is not guaranteed by merely using the inverse-sounding name encode after decode. The encoder must know which part is data and which delimiters belong to the surrounding structure. Encoding the complete path as a single data component would answer another question.
The learner’s check is structural: after construction and parsing under the same stated rules, do we recover the original component list? A round trip can verify one defined relationship. It does not establish that another framework with different accepted values or normalisation rules interprets the path identically. Keep the contract alongside the round-trip result.
CHAPTER 16 OF 26 · Audit and transfer
16. Keep canonicalisation separate from arbitrary equivalence
Canonicalisation chooses a preferred representation under a stated notion of equivalence. It is useful only when the transformation preserves the distinctions relevant to the task.
The existing article on canonicalisation and the information it removes explains this broader idea. Our path example supplies a specific boundary: turning encoded identifier data into a structural separator can change the route rather than merely tidy its spelling.
Similarly, two addresses returning similar content do not automatically have interchangeable meaning for editing, caching, access rules or analytics. A resource can have several deliberate representations, and an application can distinguish values that look almost identical to a reader.
For a practical note, name what equivalence is claimed: same parsed URL record, same application identifier, same displayed document or same result for a particular operation. Then state the evidence. These relations can coincide in a simple case without being identical concepts. A normalisation routine should not quietly expand its promise from one relation to every possible use of an address.
Preserve resource identity in logs and comparisons
A log entry is useful only when a later reader understands which representation it stores. A raw written path, a decoded component list and a display-friendly label can all be legitimate records, but they support different comparisons.
If one log records A%2FB and another records the decoded item A/B, a text comparison can report a difference even when both describe the same item under the stipulated contract. Conversely, joining a decoded list can make two different structures look like the same plain text.
Store enough context to reproduce the interpretation, under the organisation’s appropriate data-handling arrangements. A small synthetic debugging record can include a stage name, encoded path, parsed components and contract version without requiring real user data.
The goal is not to maximise logging. It is to retain the distinction needed for the actual question. A concise trace with known representation types can be more informative than a large collection of unlabelled address strings. When a field changes meaning, explain the change before treating its counts as a continuous trend.
CHAPTER 17 OF 26 · Audit and transfer
17. Do not infer route correctness from cache behaviour
A page appearing quickly, or appearing repeatedly from a cache, does not establish which route values the application would interpret on a fresh request. Caching introduces another representation and reuse boundary.
The guide to response age across more than one cache develops the separate timing account. Its freshness calculation is not a proof that a link identifies the intended resource or that every layer agrees on a path.
In a fictional investigation, a cached response can make two written inputs appear to produce the same page. That observation may prompt a question about cache keys, application routing or both. It should not be converted immediately into a general claim that the inputs are equivalent.
State the operation and conditions actually checked. Was the evidence a stored page, a fresh route trace or a handler’s parsed arguments? Different records can help answer the problem, but they should not be substituted for one another. This keeps a representation error from being hidden by an apparently successful page display.
A second fictional service uses the route components archive and item. Its item identifier is Q/R%S. Under the stipulated component encoder, the written path is /archive/Q%2FR%25S.
Before reading the answer, apply each teaching pipeline. Count the resulting meaningful components, then write the item value that the route contract expects. Decode only one layer at each declared stage.
Split-then-decode produces two component values: archive and Q/R%S. Decode-then-split first produces /archive/Q/R%S and then three values: archive, Q and R%S. The newly visible percent sign does not authorise another decoding pass, and the trailing %S is not a valid percent-encoded byte triplet.
The changed example combines a data slash and a represented percent sign. A learner who only remembers the first example’s letters can miss the second distinction. Check both the list shape and the data value. The task is complete when the learner can explain why the two pipelines disagree, not just report that one produced a longer list.
CHAPTER 19 OF 26 · Audit and transfer
19. Check a changed form value in its own format
Now change format rather than merely changing the path’s letters. A fictional form value is written Q%2FR%25S+T%2BU under application/x-www-form-urlencoded rules.
Applying that format’s stated parsing order gives Q/R%S T+U. The raw plus becomes a space, while %2B becomes a literal plus after percent-decoding. The represented percent sign remains data in the resulting text.
If the same characters were treated as path-component text under a contract that does not replace plus with space, the raw plus would not acquire the form-specific meaning. The expected result therefore depends on the input format as well as the byte sequence.
This transfer check asks the learner to stop before reusing a familiar decoding rule. First name the format and its boundaries, then apply its transformations. A calculation that is correct for one format can be inappropriate in another. The resulting strings can both look plausible, which is why the source contract belongs in the explanation rather than being left as an assumption.
For an authorised implementation review, choose representative values from the actual accepted identifier set. Include ordinary characters, supported encoded data and explicit rejection cases. Record expected structured values before observing the result.
Keep the scope to a controlled test environment and documented task. The objective is to verify the route contract, not to invent a complete parser or infer security from a few successful examples. Configuration, framework version and intermediary behaviour can affect the actual chain.
A useful result contains the original input, the stage inspected, the parsed value, any rejection and the resource or handler reached. If those disagree, investigate the first divergence. Do not simply change a visible link until the final page looks acceptable while leaving an inconsistent interpretation elsewhere.
After a correction, check both the changed example and an ordinary valid case. This guards the reader’s task: a repair should preserve intended navigation as well as address the observed discrepancy. The exact checks should follow the real contract and evidence, rather than a universal checklist copied from the toy catalogue.
CHAPTER 21 OF 26 · Audit and transfer
21. Connect route identity with dependable editing
A resource address also appears in editing and publishing workflows. If a link is rewritten or a component changes interpretation, an editor may inspect one record while intending to update another. This is different from two editors saving different versions of the same record.
The guide to preserving editors' work when a save uses an outdated version explains that concurrency boundary. Correct resource identity is one prerequisite for asking its version question meaningfully.
Likewise, section links when chapters move concerns stable document destinations and anchors. A valid address and a meaningful section target support different parts of the same reader journey.
These connections should remain distinct in an explanation. First establish the intended resource and component values. Then check the relevant document state, section destination or save version. One successful stage does not certify the whole task, but keeping the stages named makes the remaining question easier to locate and resolve.
Consider the claim: “Encoded slashes and slashes are the same character, so decoding the address first cannot change anything.” It ignores the stage at which a character is interpreted as structure. The catalogue counterexample produces different component lists from the same input.
Another claim says: “The function decoded successfully, so the route is correct.” Successful transformation does not establish that the output type or application meaning is correct. A third says: “Decoding twice is safer because nothing encoded remains.” The represented-percent example shows why repeating the interpretation can change data again.
Repair the first unsupported step. Name the representation, identify its delimiters and state which values the next stage is supposed to receive. Then compare the actual intermediate result with that expectation.
This is a useful teaching habit beyond URLs. Data and instructions can share the same visible symbols. A reliable explanation follows the rules that assign their roles instead of assuming that the visible text alone carries an unchanging meaning through every transformation.
For a repair route, write the fictional catalogue paths on cards. Mark literal separators, split into component cards and decode the data while keeping each card intact. Compare that with decoding the original line before cutting it apart.
For a stabilisation route, add a represented percent sign, an encoded tilde and an internal empty component. Require the learner to name which condition each example tests and whether the expected outcome is a preserved value or a rejection under the supplied contract.
For an extension route, create a representation ledger for a small authorised demonstration application. Compare an encoded path, parsed URL record, route arguments and a reconstructed link. Explain every transformation and verify a changed identifier independently.
These routes progress from concrete boundaries to structured records. The learner should eventually identify when a mature parser or framework contract supplies a rule that the classroom model intentionally omitted. Recognising that limit is part of understanding the mechanism. It is more useful than turning a short string exercise into an unsupported claim about every website.
Is percent-encoding the same as encryption?
No. In these examples it represents bytes in a written address format. It does not conceal the identifier from someone who knows the encoding rule.
Must every application accept an encoded slash in an identifier?
No. Acceptance and rejection follow the relevant route and infrastructure contract. The exercise compares explicit rules rather than assigning one universal server policy.
Is decoding an unreserved character the same issue?
It can preserve the generic identifier interpretation without creating a reserved delimiter. Keep that class distinct from encoded structural characters.
Does a browser's readable display prove the stored address changed?
No. Display, copying, parsing and application interpretation are different records. Inspect the appropriate representation for the actual question.
Can one successful example verify the whole route system?
No. It establishes a result for that input and those conditions. Choose representative cases from the actual contract and preserve the scope of the conclusion.
CHAPTER 25 OF 26 · Practise and continue
25. Continue through the relevant website guides
Return to the Websites subject guide for complete user journeys. For address construction, continue to relative references and base changes and the wider explanation of canonicalisation.
For destination maintenance, read section links across chapter changes. For separate state and timing questions, read outdated editing versions and response age across caches.
The wider learning routes are How X Works and The Gold Standard of Education: learning transfers into life. The transferable skill is to preserve meaning when a structured value moves between written representations and processing stages.
CHAPTER 26 OF 26 · Practise and continue
26. Sources and a final representation check
The primary technical references are RFC 3986, published in January 2005, and the WHATWG URL Standard, whose page was marked updated on 19 October 2026 when checked on 23 October 2026. The former supplies the generic reserved/data distinction; the latter supplies contemporary URL and form-data parsing context.
The catalogue identifiers, pipeline comparisons and transfer exercises are original constructions. They do not report the behaviour of a deployed service or replace its implementation documentation. No live destination is implied by a fictional path in the examples.
Before accepting a route explanation, identify the original representation, each structural boundary, the decoded data and the expected output type. Then check that reconstructing the address preserves the intended component values under the same contract. If a later stage changes those values, record the divergence rather than treating a readable final string as proof that nothing important changed.