12.32.1
Release : play-frontend-hmrc 12.32.1
Propagate the usage of service navigation into query params of links to common platform components like contact forms and accessibility statements
This is to address an accessibility issue - services using service nav linking to pages of these common platform components which don't use service nav yet are non compliant with wcag 2.2 rules around consistent identification due to the changing labelling of the language switch controls
And we can't enable service nav on those services without making all services not yet using service nav non-compliant
Although this is a patch release - some components now need a request header in scope which didn't before, and the shape of service nav config has changed - this should hopefully not require any changes for most use cases in hmrc services
To enable this behaviour, we needed a way to determine if service nav is being used so that our components can display the correct urls to common components
To do that, we've repurposed the feature flag we added to force use of service nav before migrating to v13 to enable people to migrate without any code changes
That feature flag was controlled only by config before, and that meant that services that needed to be able to conditionally display pages using service nav couldn't use it - but now it's an interface - which our components which need to change their output depending on use of service nav can depend on
It has a default config based implementation matching the previous behaviour, but that can be overridden by services which need more granular control with different strategies- we've included two generic strategies for different use cases - one where use of service nav is determined by a query parameter in the url and another where use of service nav is determined by a play framework request attribute
Examples of how to use each will be detailed in guidance that will be included as part of this pull request
What's been done
Important
these common platform services will not yet be interpreting this context to display their own pages with service navigation
- propagate service nav usage to tracking.js script tag via data attribute
- propagate to standard phase banner urls
- propagate to footer links
- propagate to accessibility statement links
- propagate to report technical problem links
Decisions
- should we propagate service nav usage to tracking.js via a data attribute?
- probably should start passing it and tracking.js can also have a fallback- I guess the risk of not passing it is that the user journey could be using service nav but the page currently on has nothing on it to indicate that if it's not got welsh translation or service name - there's a need for consistency with pages earlier than current page in journey
- what query param to use?
?useServiceNavigationisn't intended to be understandable / editable by users - just something added to end of url automatically and won't be around forever
- should query param be a boolean or based on presence
- trade-off is that based on presence we can't fallback to config - but seems like when you are at the point you want to have it determined by config you can just switch to the by config strategy
- where should the "how to change service navigation config strategy`' be documented? We will have a blog post - it seems like having it in the repo hides it a bit and it might be easier to have it in a release note or something like that on github and link to that from blog post - makes it easy for us to tweak it there if needed adhoc - though I'm presuming it's only a small number who might refer to it
- for now will document here, and include it in the blog post or link to it in a google doc that we can make updates to
Embedded services that want to display pages with and without service nav during migration
Important
This guidance only applies to services using play-frontend-hmrc v12 - once you are using play-frontend-hmrc v13 it isn't possible to opt-out of the use of service navigation.
The conditional display of pages within a service using service nav and not - is something which should only be needed by embedded services which participate in user journeys initiated by other services - and only in the case where you can't coordinate the use of service nav across all those initiating services at the same time - and you want to allow them to update to use service navigation incrementally for a period of time.
Previously you would not use the service navigation feature flag in this case - instead you would just explicitly pass the service nav to our components yourself depending on when you wanted it to display
However, now that we have some deeply nested components that need to know if the service nav is being used - rather than making a lot of api changes to thread that context through components, we've turned the feature flag into an interface that you can swap out with another implementation if needed - and the only which needs to be present to determine it's usage is a request header which is already present in most cases.
use service nav based on play-frontend-hmrc.forceServiceNavigation feature flag from config (default strategy)
This is how it behaved before, you don't need to do anything for it to continue to behave like this - if you were using this to enable service nav then once you update you won't likely won't need to do anything, and the necessary links to our common platform services like contact forms, accessibility statements, and global info pages like terms and conditions will now have an additional query param to tell those pages that they should be displayed with the service navigation.
use service nav based on query param ?useServiceNavigation
to enable this you need to disable the default strategy and enable the module which configures this
in your application.conf
play.modules.disabled += "uk.gov.hmrc.hmrcfrontend.config.DefaultServiceNavigationConfigModule"
play.modules.enabled += "uk.gov.hmrc.hmrcfrontend.config.ServiceNavigationCanBeControlledByQueryParamModule"
then if a request comes in with ?useServiceNavigation the page will be displayed using the service nav as if play-frontend-hmrc.forceServiceNavigation had been set, otherwise it will be displayed as normal.
if there are parts of your service that should change based on the use of service navigation then you would need to inject ServiceNavigationConfig and make your changes based on the forceServiceNavigation feature flag -which with this strategy in place will be determined by the presence of the query parameter only
if you have internal links through anchor tags and form actions to other pages in your service, then you will need to propagate the query param through those urls - to help with this, there is a helper ServiceNavigationConfig.propagateViaQueryParam(url: String) which can append the parameter to a url for you if service navigation is enabled
use service nav based on a request attribute (or indicate to our components your use of it)
Request attributes allow you to store extra information inside request objects to be used later in the processing of a request. They can be accessed through the request header which is normally passed through views. We've added a strategy that checks for the presence and value of a request attribute to determine if the service nav is being used so that we can link to the correct versions of pages of common platform components.
in your application.conf
play.modules.disabled += "uk.gov.hmrc.hmrcfrontend.config.DefaultServiceNavigationConfigModule"
play.modules.enabled += "uk.gov.hmrc.hmrcfrontend.config.ServiceNavigationCanBeControlledByRequestAttrModule"
then in your actions or filters in your service - to indicate that a request will be using or should use service navigation - you would set it on the request something like this if set in an action:
import uk.gov.hmrc.hmrcfrontend.config.ServiceNavigationCanBeControlledByRequestAttr.UseServiceNavigation
class ExampleController {
def index(journeyId: String): Action[AnyContent] = Action.async { request =>
Journey.findById(journeyId).map {
case Some(journey) => {
given Request[AnyContent] = request.addAttr(UseServiceNavigation, journey.shouldUseServiceNavigation)
Ok(renderPage(journey))
}
case None =>
NotFound("this is just an example to help you understand, please don't copy this code verbatim")
}
}
}
Where UseServiceNavigation should be set to true or false, and will fall back to the value of play-frontend-hmrc.forceServiceNavigation - and the example above gives a made up example of how you might map that from some state you have saved about the current journey - maybe from when it was initiated. You could also set this request attribute in a filter for all requests.