Add Embed Card Component and Update Cookies#3963
Conversation
✅ You can preview this change here:
To edit notification comments on pull requests, go to your Netlify site configuration. |
eddda80 to
8aa19bc
Compare
d69467a to
3676f37
Compare
797f9a8 to
32a9744
Compare
32a9744 to
005c467
Compare
|
When it's approved, the page will be set to DRAFT. |
005c467 to
8fa1fa9
Compare
owenatgov
left a comment
There was a problem hiding this comment.
Couple of comments. Overall looking good!
|
|
||
| {% from "_cookie-banner.njk" import cookieBanner %} | ||
|
|
||
| <p class="govuk-!-font-size-24"> |
There was a problem hiding this comment.
You could use govuk-body-l here. Functionally they're the same but for neatness we should probably be using native styles rather than overrides where we can.
| <p class="govuk-!-font-size-24"> | |
| <p class="govuk-body-l"> |
| width: 100%; | ||
| height: 100%; | ||
| background: | ||
| url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3OSIgaGVpZ2h0PSI1NSIgdmlld0JveD0iMCAwIDc5IDU1IiBmaWxsPSJub25lIj4KPHBhdGggZD0iTTM5Ljc1MDMgMEg0MC4xODYxQzQ0LjIxMDQgMC4wMTQ2ODEgNjQuNjAxNiAwLjE2MTQ5MiA3MC4wOTk2IDEuNjM5MzhDNzEuNzYxNyAyLjA5MDQyIDczLjI3NjMgMi45Njk1OSA3NC40OTIgNC4xODkwMkM3NS43MDc2IDUuNDA4NDYgNzYuNTgxOCA2LjkyNTQ1IDc3LjAyNzIgOC41ODg0Qzc3LjUyMTcgMTAuNDQ4IDc3Ljg2OTMgMTIuOTA5NSA3OC4xMDQzIDE1LjQ0OTNMNzguMTUzMyAxNS45NTgzTDc4LjI2MSAxNy4yMzA2TDc4LjMwMDEgMTcuNzM5NkM3OC42MTg0IDIyLjIxMjQgNzguNjU3NSAyNi40MDE0IDc4LjY2MjQgMjcuMzE2NVYyNy42ODM1Qzc4LjY1NzUgMjguNjMyOSA3OC42MTM1IDMzLjEwNTcgNzguMjYxIDM3Ljc2NDVMNzguMjIxOCAzOC4yNzgzTDc4LjE3NzcgMzguNzg3M0M3Ny45MzI5IDQxLjU4NjQgNzcuNTcwNiA0NC4zNjYgNzcuMDI3MiA0Ni40MTE2Qzc2LjU4MzIgNDguMDc1MiA3NS43MDk0IDQ5LjU5MjkgNzQuNDkzNiA1MC44MTI2QzczLjI3NzcgNTIuMDMyMiA3MS43NjI0IDUyLjkxMDkgNzAuMDk5NiA1My4zNjA2QzY0LjQyMDQgNTQuODg3NCA0Mi44MzQ3IDU0Ljk5NTEgMzkuODQzNCA1NUgzOS4xNDgxQzM3LjYzNTMgNTUgMzEuMzc4NSA1NC45NzA2IDI0LjgxOCA1NC43NDU1TDIzLjk4NTggNTQuNzE2MkwyMy41NTk4IDU0LjY5NjZMMjIuNzIyNiA1NC42NjIzTDIxLjg4NTQgNTQuNjI4MUMxNi40NTExIDU0LjM4ODMgMTEuMjc2MiA1NC4wMDE3IDguODkxOSA1My4zNTU3QzcuMjI5NzIgNTIuOTA2NSA1LjcxNDgyIDUyLjAyODUgNC40OTg5OSA1MC44MDk3QzMuMjgzMTUgNDkuNTkxIDIuNDA5MDcgNDguMDc0MyAxLjk2NDMgNDYuNDExNkMxLjQyMDg2IDQ0LjM3MDkgMS4wNTg1NyA0MS41ODY0IDAuODEzNzc2IDM4Ljc4NzNMMC43NzQ2MDkgMzguMjczNEwwLjczNTQ0MyAzNy43NjQ1QzAuNDkzODIyIDM0LjQ0ODUgMC4zNTk5MzIgMzEuMTI1NiAwLjMzMzk4NCAyNy44MDFMMC4zMzM5ODQgMjcuMTk5QzAuMzQzNzc2IDI2LjE0NjkgMC4zODI5NDMgMjIuNTEwOSAwLjY0NzMxOCAxOC40OTgxTDAuNjgxNTg5IDE3Ljk5NEwwLjY5NjI3NiAxNy43Mzk2TDAuNzM1NDQzIDE3LjIzMDZMMC44NDMxNTEgMTUuOTU4M0wwLjg5MjEwOSAxNS40NDkzQzEuMTI3MTEgMTIuOTA5NSAxLjQ3NDcxIDEwLjQ0MzEgMS45NjkxOSA4LjU4ODRDMi40MTMyMSA2LjkyNDc4IDMuMjg2OTcgNS40MDcwNyA0LjUwMjg1IDQuMTg3NDNDNS43MTg3NCAyLjk2Nzc5IDcuMjM0MDIgMi4wODkwNyA4Ljg5NjggMS42MzkzOEMxMS4yODExIDEuMDAzMiAxNi40NTYgMC42MTE3MDkgMjEuODkwMyAwLjM2NzAyNUwyMi43MjI2IDAuMzMyNzdMMjMuNTY0NyAwLjMwMzQwOUwyMy45ODU4IDAuMjg4NzI3TDI0LjgyMjkgMC4yNTQ0NzJDMjkuNDgyMyAwLjEwNDYwMSAzNC4xNDM3IDAuMDIxMzk5NCAzOC44MDU0IDAuMDA0ODkzOUgzOS43NTAzVjBaTTMxLjY2NzMgMTUuNzA4N1YzOS4yODY0TDUyLjAxOTMgMjcuNTAyNEwzMS42NjczIDE1LjcwODdaIiBmaWxsPSIjRUEzMzIzIi8+CjxwYXRoIGQ9Ik0zMS42NjggMTUuNzA4N1YzOS4yODY1TDUyLjAxOTkgMjcuNTAyNUwzMS42NjggMTUuNzA4N1oiIGZpbGw9IndoaXRlIi8+Cjwvc3ZnPg==") |
There was a problem hiding this comment.
Where is this coming from?
There was a problem hiding this comment.
Oh, this is just me converting the YouTube logo to a base64 string. Can add it as an actual image if that's preferable.
There was a problem hiding this comment.
Is there a benefit to either appraoch? The only downside I can see here is that it amkes the file slightly less legible. If we can add a comment explaining what it is and why that's good enough for me.
There was a problem hiding this comment.
One thing to think about: inlined in the CSS, it adds Kb of downloads to each page, even those that don't show any video. If referenced as an external URL, browsers will only download it on pages showing videos 😊
There was a problem hiding this comment.
I'll switch to using an asset :)
views/partials/_cookie-banner.njk
Outdated
| <p class="govuk-body">You’ve accepted analytics cookies. You can <a class="govuk-link" href="/cookies/">change your cookie settings</a> at any time.</p> | ||
| {% endset %} | ||
| {%- set category -%} | ||
| {%- if not params.category -%} |
There was a problem hiding this comment.
How come we're checking for params negatively? IE: Can we change the if around so we're just checking for params.[param]?
7043be0 to
f00aa8d
Compare
f00aa8d to
f9cb361
Compare
Adds new category of cookies to cookie functions and the cookie page. Change default values of preference cookies to `null`. This means that we can now track if the user has been asked at all what their cookie preference is for different categories.
Change `_cookie-banner.njk` to a macro that take parameters including what category of cookie the banner is setting and the HTML that should be displayed for different states of the cookie banner. Allow `cookie-banner.mjs` to have a different cookie category than 'analytics' to be set (by using data varibles on the target module). Move the `GDS_CONSENT_COOKIE_VERSION` to `_generic.njk` so that this only gets set once at the top each page instead of multiple times by different cookie banner instances. Add new tests for multiple categories of cookie banners on the same page. Update existing tests.
Create the Design System Day 1 page, which will consist of embeds of talks of the speakers.
f9cb361 to
5399fe6
Compare
Update `application.mjs` to support multiple cookie banners on a page. Create new Embed Card component. If require cookie not set (or script fails to execute) placeholder image that links to YouTube video will be created. If cookie is set then placeholder will be replaced with a YT embed. Add `lazyEmbedObserver` in `application.mjs`. Embed Card component will only be initialized when the placeholder is in the viewport. This means for a page with lots of embeds, the page the performance hit will be limited if the user doesn't scroll the entire page. Add tests for new Embed Card component.
5399fe6 to
781b769
Compare
romaricpascal
left a comment
There was a problem hiding this comment.
Apologies for the late review, it's a strong base to add embeds but I've found a couple of places we might improve things. These can be adressed in separate PRs now we've merged 😊
| }) | ||
|
|
||
| await page.setCookie({ ...cookieParam, value }) | ||
| await goTo(page, '/community/design-system-day-2024-day-1/') |
There was a problem hiding this comment.
suggestion Could we use a draft test page instead of a live content page everywhere we're running tests? This will reduce the risk of a content update screwing the tests if one day we archive or move the page for DS Day day 1.
|
|
||
| const $embedCards = document.querySelectorAll('[data-module="app-embed-card"]') | ||
|
|
||
| const lazyEmbedObserver = new IntersectionObserver(function ( |
There was a problem hiding this comment.
question Looks like there's a slim gap of lack of support for IntersectionObserver in Safari where this code will error. Thanfully this is the last thing being initialised, so other components won't be affected, but if an error occurs due to lack of IntersectionObserver, will people still be able to navigate to the video via the link already in the page?
There was a problem hiding this comment.
suggestion For tidiness, it would be good to protect the component's initialisation with an if (IntersectionObserver in window) or something similar 😊
| {{- caller() if caller else params.content | safe -}} | ||
| <a class="app-embed-card__placeholder" href="https://www.youtube.com/watch?v={{ params.ytId }}"> | ||
| <div class="app-embed-card__placeholder-thumb-container"> | ||
| <img class="app-image--no-border app-embed-card__placeholder-thumb-image" alt="placeholder for {{ params.title }} youtube embed" src="https://img.youtube.com/vi/{{ params.ytId }}/hqdefault.jpg"> |
There was a problem hiding this comment.
nitpick Worth checking with @selfthinker, but I don't think the alternative text brings any information to a person using assistive technology and will just lengthen the name of the link to "placeholder for <VIDEO_TITLE> youtube embed <VIDEO_TITLE>".
If we set the alt text to {{ params.title}} this will:
- provide a fallback in case the placeholder image doesn't load for whatever reason
- reduce the markup, as the next span will be redundant for labelling the link and we can get rid of it
There was a problem hiding this comment.
question A couple of questions about the URL we use for that placeholder:
- is it from an official API from YouTube or discovered from how their embed works? how likely is it to change in the future?
- it effectively embeds content from another domain into our site, are we sure it doesn't set cookies prior to users having given their consent (and won't do in the future)?
All in all, it might be safer to have the placeholder images in our repo (we're the ones making the videos anyway so we have the images, in any case).
| lazyEmbedObserver.unobserve(lazyEmbed) | ||
| lazyEmbedObserver.observe(lazyEmbed) |
There was a problem hiding this comment.
question I'm not following what this is doing exactly, what's stopping observing and observing again doing?
| } | ||
|
|
||
| const observer = new MutationObserver(callback) | ||
| observer.observe(campaignCookieBanner, { |
There was a problem hiding this comment.
question Do we need to unobserve the mutations at some point? Thinking the CookieBanner may have two mutations happening: the click for 'Accept/Refuse', then the click to dismiss the banner?
| } | ||
| } | ||
|
|
||
| .app-campaign-cookie-banner .govuk-grid-column-two-thirds { |
There was a problem hiding this comment.
nitpick This makes the semantic of govuk-grid-column-two-thirds surprising. Is there a way we could use either:
- a width override class
- a different class to hook the styles to than
.govuk-grid-column-two-thirds
| const ytId = ytHref.match( | ||
| /(youtu\.be\/|youtube\.com\/(watch\?(.*&)?v=|(embed|v)\/))([^?&"'>]+)/ | ||
| )[5] | ||
|
|
||
| const iframe = this.createIframe(ytId, title) |
There was a problem hiding this comment.
suggestion Given the Nunjucks component knows the ID, passing it through data-attribute would avoid us maintaining a RegExp to extract it from a URL we've built ourselves.
| @@ -0,0 +1,17 @@ | |||
| .app-embed-card__placeholder-thumb-container { | |||
There was a problem hiding this comment.
issue If the image does not load, the thumbnail container becomes very short. Best to give it a set aspect ratio (we'll still need the padding hack to do it).
The aspect ratio would also be beneficial to the iframe while it's loading, to avoid layout shifts.
| <div class="govuk-grid-column-two-thirds-from-desktop"> | ||
| {{- caller() if caller else params.content | safe -}} | ||
| <a class="app-embed-card__placeholder" href="https://www.youtube.com/watch?v={{ params.ytId }}"> | ||
| <div class="app-embed-card__placeholder-thumb-container"> |
There was a problem hiding this comment.
question Could the <a> serve as thumb container if it was display: block and lighten the HTML a little?
| @@ -0,0 +1,22 @@ | |||
| {% macro embedCard(params) %} | |||
| <div class="govuk-grid-row" data-module="app-embed-card"> | |||
There was a problem hiding this comment.
suggestion Given the role of the JavaScript is to swap the link for an iframe, having it set on the <a> element would help narrow down which bits of the markup it would affect.
NB: Content will come in a later PR. Felt that the work in PR should be separated as it was getting quite large.
What
Why
We want to add the ability to embed YouTube videos to the Design System website. This requires new preference cookies needing to be set because embeddable iframes from external sites can/do set cookies themselves.
Addresses #3931