Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Components failing initialisation break due to .js-enabled styles #999

Open
NickColley opened this issue Sep 14, 2018 · 10 comments
Open

Components failing initialisation break due to .js-enabled styles #999

NickColley opened this issue Sep 14, 2018 · 10 comments
Labels
🐛 bug Something isn't working the way it should (including incorrect wording in documentation) javascript

Comments

@NickColley
Copy link
Contributor

NickColley commented Sep 14, 2018

js-blocked

It is possible for components to be in a completely broken state if the user has JavaScript enabled but the GOV.UK Frontend bundle fails to download.

Previously we detected the presence of GOV.UK globally on window, but we removed this since we could not be sure if people would be using bundlers which will not output a global.

https://github.com/alphagov/govuk_template/blob/master/source/views/layouts/govuk_template.html.erb#L113

We could consider, injecting a global whenever a component is loaded that can remove js-enabled.

Potentially something like:

if (not already injected) {
   window.___GOVUKFrontendComponentInitialised___
}
// tabs.js
import 'inject-global-initialised'
// only injects if not already injected before
inject()

// rest of tabs code here
// template.njk

<script>if(!window.___GOVUKFrontendComponentInitialised___) { // remove js-enabled }</script>
</body>

https://trello.com/c/oRDkiAz9/1448-frontend-components-appeared-styled-when-js-blocked

@NickColley NickColley added the 🐛 bug Something isn't working the way it should (including incorrect wording in documentation) label Sep 14, 2018
@NickColley
Copy link
Contributor Author

NickColley commented Jan 25, 2019

Potentially by solving #1127 we could then use that to solve this issue.

Since they both rely on knowing of instances of GOV.UK Frontend components on the page.

We could then say if no instances were set, then assume something blew up.

@edwardhorsford
Copy link
Contributor

We had a similar issue in my service this week. For reasons our service's js file for IE failed to compile so our service's js wasn't available in IE - but we still had the js-enabled class. This caused the worst of both worlds - fields with conditional content were hidden and there was no way to get to them.

If there are recommended solutions - like testing for a variable I'd be keen to hear them.

@shaquillaevelyn
Copy link

Hello all,

Currently experiencing this issue- what was the fix for this?

Thanks

js-blocked

It is possible for components to be in a completely broken state if the user has JavaScript enabled but the GOV.UK Frontend bundle fails to download.

Previously we detected the presence of GOV.UK globally on window, but we removed this since we could not be sure if people would be using bundlers which will not output a global.

https://github.com/alphagov/govuk_template/blob/master/source/views/layouts/govuk_template.html.erb#L113

We could consider, injecting a global whenever a component is loaded that can remove js-enabled.

Potentially something like:

if (not already injected) {
   window.___GOVUKFrontendComponentInitialised___
}
// tabs.js
import 'inject-global-initialised'
// only injects if not already injected before
inject()

// rest of tabs code here
// template.njk

<script>if(!window.___GOVUKFrontendComponentInitialised___) { // remove js-enabled }</script>
</body>

https://trello.com/c/oRDkiAz9/1448-frontend-components-appeared-styled-when-js-blocked

E

@selfthinker
Copy link

selfthinker commented Jun 8, 2021

When www.gov.uk was down today and I wanted to send someone a link to it via the Wayback Machine, I found that I couldn't get to any of the main links within an accordion because the JavaScript wasn't archived. Although the page in question was not using the accordion from the Design System, I checked that the effect on the Design System accordion would be the same.

So, here is that real world example: http://web.archive.org/web/20210205010100/https://www.gov.uk/service-manual/helping-people-to-use-your-service

Usually, when you click on "Meeting accessibility requirements", the section underneath would open and reveal a couple of links. This is worse than Nick's original example because it's impossible to get to the links and you cannot even see that anything is missing.

@shaquillaevelyn
Copy link

useEffect(() => {
document.documentElement.classList.add(‘govuk-template’);
document.body.classList.add(‘js-enabled’, ‘govuk-template__body’);
}, []);

Place this code into your root component, this fix works for me!!

Hello all,

Currently experiencing this issue- what was the fix for this?

Thanks

js-blocked It is possible for components to be in a completely broken state if the user has JavaScript enabled but the GOV.UK Frontend bundle fails to download. Previously we detected the presence of `GOV.UK` globally on window, but we removed this since we could not be sure if people would be using bundlers which will not output a global. https://github.com/alphagov/govuk_template/blob/master/source/views/layouts/govuk_template.html.erb#L113 We could consider, injecting a global whenever a component is loaded that can remove js-enabled. Potentially something like: ```js if (not already injected) { window.___GOVUKFrontendComponentInitialised___ } ```
// tabs.js
import 'inject-global-initialised'
// only injects if not already injected before
inject()

// rest of tabs code here
// template.njk

<script>if(!window.___GOVUKFrontendComponentInitialised___) { // remove js-enabled }</script>
</body>

https://trello.com/c/oRDkiAz9/1448-frontend-components-appeared-styled-when-js-blocked

E

@trang-erskine trang-erskine removed the ⚠️ high priority Used by the team when triaging label Oct 27, 2021
@colinrotherham colinrotherham changed the title If GOV.UK Frontend fails to initialise but the end-user has JavaScript enabled components will fail Components that don't initialise can remain broken due to .js-enabled styling Dec 13, 2022
@colinrotherham colinrotherham changed the title Components that don't initialise can remain broken due to .js-enabled styling Components failing initialisation break due to .js-enabled styles Dec 13, 2022
@colinrotherham
Copy link
Contributor

Adding a list of scenarios from:

For context: We improved Accordion sections to be visible during page load in #3053 but for slow-loading pages we saw a visual layout shift as each section flickered closed (from open) after initialisation

We'd like to review similar components load with:

  1. JavaScript off
  2. JavaScript on but crashed
  3. JavaScript on but skipped checks
  4. JavaScript on but took too long

(Where "skipped checks" could be an early return false after a query selector check fails)

colinrotherham added a commit that referenced this issue Dec 13, 2022
When loading the Accordion component with JavaScript enabled, this change restores `display: none` on section content

For context, we switched to `display: inherit` previously:
#3053

But for slow-loading pages we saw a visual layout shift as each section flickered closed (from open) after initialisation

We’d like to take another look at how components load in:
#999
colinrotherham added a commit that referenced this issue Dec 19, 2022
When loading the Accordion component with JavaScript enabled, this change restores `display: none` on section content

For context, we switched to `display: inherit` previously:
#3053

But for slow-loading pages we saw a visual layout shift as each section flickered closed (from open) after initialisation

We’d like to take another look at how components load in:
#999
colinrotherham added a commit that referenced this issue Dec 22, 2022
When loading the Accordion component with JavaScript enabled, this change restores `display: none` on section content

For context, we switched to `display: inherit` previously:
#3053

But for slow-loading pages we saw a visual layout shift as each section flickered closed (from open) after initialisation

We’d like to take another look at how components load in:
#999
colinrotherham added a commit that referenced this issue Jan 9, 2023
When loading the Accordion component with JavaScript enabled, this change restores `display: none` on section content

For context, we switched to `display: inherit` previously:
#3053

But for slow-loading pages we saw a visual layout shift as each section flickered closed (from open) after initialisation

We’d like to take another look at how components load in:
#999
@36degrees
Copy link
Contributor

An example of this came up last Friday in an incident on GOV.UK. A change was rolled out which introduced an error in their analytics JavaScript, which caused the JS for other components to fail. From their incident doc (internal, only visible to folks from GDS):

A change to JavaScript code in govuk_publishing_components that loads Google Analytics made it though to production in a bad release of Static, resulting in user interface code failing to load. This broke all JavaScript features (search button, menu bar etc.) on pages which have scroll-tracking analytics. This made all content behind "accordion" drop-down widgets — such as those on the www.gov.uk/coronavirus landing page — unviewable to Chrome and Firefox users.

Off the back of this, GOV.UK have wrapped the initialisation of each component in a try / catch block to try and limit the impact of errors in any individual JavaScript module.

Although we now have a recent example of why this is a problem, it's still come up (surprisingly) rarely since this issue was raised, so at the minute this isn't going to be prioritised over the work planned for the next quarter, but we hope to look at this soon.

@36degrees
Copy link
Contributor

Before they get lost, a scrappy attempt to capture potential ideas to explore from various people on Slack, in no particular order:

  • remove the js-enabled class from the body if an error occurs
  • consider using a different kind of progressive enhancement for the accordion – e.g. a link and a :target selector so we have a layout closer to the final one until JS kicks in
  • use <details> elements (probably not – see Accordion component #958 (comment), https://daverupert.com/2019/12/why-details-is-not-an-accordion/, https://adrianroselli.com/2019/04/details-summary-are-not-insert-control-here.html and https://www.scottohara.me/blog/2022/09/12/details-summary.html)
  • have a “smoke and mirrors” class that we temporarily add with a setTimeout? This is the maximum time the Accordion should stay closed to avoid layout shift. Bit like how we try to load an @font-face by staying blank before falling back, but ideally the Accordion would finish loading before the “smoke and mirrors” class gets removed—if not they fail safe to open state
  • our all.js script that initialises all of our modules would be subject to the same kind of issue that happened to GOV.UK. If an early module throws, later modules won’t get initialised. We’re quite defensive in the code initialising each module already to avoid throwing, but we may want to give it a proper look (and maybe implement something akin to the suggestion to wrap initialising loop in try/catch to let further modules work OK).
  • it’s also likely that many services have the same need of initialising multiple JavaScript modules in a row, without the failure of one breaking those that come after. It could be something we provide some solution for as part of govuk-frontend (not necessarily a trivial thing if we need to consider modules trying to call each other and maybe having to load asynchronously, so we may only be able to provide only part of a solution).

@andysellick
Copy link
Contributor

andysellick commented Jan 18, 2023

On GOV.UK we've just implemented wrapping each module initialisation in a try/catch block. It should stop one module from taking down the whole page, but won't solve the accordion problem if it's the accordion that fails to initialise properly.

@romaricpascal
Copy link
Member

The spike-fail-better branch proposes a way to detect when JavaScript has not loaded to reset some styles. We'd need to figure whether it's necessarily a breaking change and how this would apply to the other components than the Accordion.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🐛 bug Something isn't working the way it should (including incorrect wording in documentation) javascript
Projects
None yet
Development

Successfully merging a pull request may close this issue.