---
title: URI fragments in redirect
description: "URI fragments are optional last parts of a URL for a document, typically used to identify or navigate to a particular part of the document. The fragment part follows the URL after a hash #, for example https://www.rfc-editor.org/rfc/rfc1234#section5."
component: pinggateway
version: 2025.9
page_id: pinggateway:gateway-guide:fragment
canonical_url: https://docs.pingidentity.com/pinggateway/2026/gateway-guide/fragment.html
llms_txt: https://docs.pingidentity.com/pinggateway/llms.txt
docs_for_agents: https://developer.pingidentity.com/build-with-ai/docs-for-agents.md
keywords: ["Configuration", "URI"]
superseded_by: https://docs.pingidentity.com/pinggateway/2026/gateway-guide/fragment.html
---

# URI fragments in redirect

URI fragments are optional last parts of a URL for a document, typically used to identify or navigate to a particular part of the document. The fragment part follows the URL after a hash `#`, for example `https://www.rfc-editor.org/rfc/rfc1234#section5`.

When an unauthenticated user requests a resource that includes a URI fragment, the user agent sends the URI but doesn't send the fragment. The fragment is lost during the authentication flow.

PingGateway provides a [FragmentFilter](../reference/FragmentFilter.html) to track the fragment part of a URI when a request triggers a login redirect.

The FragmentFilter doesn't handle multiple fragment captures in parallel. If a fragment capture is in progress while PingGateway performs another login redirect, a second fragment capture process isn't triggered and the fragment is lost.

When a browser request loads a favicon, it can cause the fragment part of a URI to be lost. Prevent problems by serving static resources with a separate route. As an example, use the route in [Serve static resources](../getting-started/start-sampleapp.html#start-sampleapp-static).

The following image shows the flow of information when the FragmentFilter is included in the SSO authentication flow:

![Flow of information when the FragmentFilter is included in the SSO authentication flow.](_images/fragment.svg)

**1-2.** An unauthenticated client requests access to a fragment URL.

**3\.** The FragmentFilter adds the AuthRedirectContext, so that downstream filters can mark the response as redirected.

**4-5.** The SingleSignOnFilter adds to the context to notify upstream filters that a redirect is pending, and redirects the request for authentication.

**6-7.** The FragmentFilter is notified by the context that a redirect is pending, and returns a new response object containing the response cookies, an autosubmit HTML form, and Javascript.

**8\.** The user agent runs the Javascript or displays the form's submit button for the user to click on. This operation POSTs a form request back to a fragment endpoint URI, containing the following parts:

* Request URI path (`/profile`)

* Captured fragment (`#fragment`)

* Login URI (`http://am.example.com/login?goto=…​`)

**9\.** The FragmentFilter creates the fragment cookie.

**10-12.** The client authenticates with AM.

**13\.** The FragmentFilter intercepts the request because it contains a fragment cookie, and its URI matches the original request URI.

The filter redirects the client to the original request URI containing the fragment. The fragment cookie then expires.

**14-19.** The client follows the final redirect to the original request URI containing the fragment, and the sample app returns the response.

This procedure shows how to persist a URI fragment in an SSO authentication. Before you start, set up and test the example in [Using the default PingAM journey](proc-sso.html).

1. In PingGateway, replace `sso.json` with the following route:

   * Linux

     `$HOME/.openig/config/routes/fragment.json`

   * Windows

     `%appdata%\OpenIG\config\routes\fragment.json`

   ```json
   {
     "name": "fragment",
     "baseURI": "http://app.example.com:8081",
     "condition": "${find(request.uri.path, '^/home/sso')}",
     "heap": [
       {
         "name": "SystemAndEnvSecretStore-1",
         "type": "SystemAndEnvSecretStore"
       },
       {
         "name": "AmService-1",
         "type": "AmService",
         "config": {
           "agent": {
             "username": "ig_agent",
             "passwordSecretId": "agent.secret.id"
           },
           "secretsProvider": "SystemAndEnvSecretStore-1",
           "url": "http://am.example.com:8088/openam/"
         }
       }
     ],
     "handler": {
       "type": "Chain",
       "config": {
         "filters": [
           {
             "name": "FragmentFilter-1",
             "type": "FragmentFilter",
             "config": {
               "fragmentCaptureEndpoint": "/home/sso"
             }
           },
           {
             "name": "SingleSignOnFilter-1",
             "type": "SingleSignOnFilter",
             "config": {
               "amService": "AmService-1"
             }
           }
         ],
         "handler": "ReverseProxyHandler"
       }
     }
   }
   ```

   Source: [fragment.json](../_attachments/config/routes/fragment.json)

   Compared to `sso.json` the `FragmentFilter` captures the fragment form data from the route condition endpoint.

2. Test the setup:

   1. In your browser's privacy or incognito mode, go to <https://ig.example.com:8443/home/sso#fragment>.

      The SingleSignOnFilter redirects the request to AM for authentication.

   2. Log in to AM as user `demo`, password `Ch4ng31t`.

      The SingleSignOnFilter passes the request to sample application, which returns the home page. Note that the URL of the page has preserved the fragment: `https://ig.example.com:8443/home/sso?_ig=true#fragment`

   3. Remove the FragmentFilter from the route and test the route again.

      Note that this time the URL of the page hasn't preserved the fragment.
