diff --git a/.changeset/olive-shrimps-marry.md b/.changeset/olive-shrimps-marry.md new file mode 100644 index 0000000000..94ade49fcf --- /dev/null +++ b/.changeset/olive-shrimps-marry.md @@ -0,0 +1,5 @@ +--- +"@khanacademy/perseus": minor +--- + +Add "do not track" query parameter to vimeo links in the video widget to ensure tracking/analytics cookies don't get set. diff --git a/packages/perseus/src/widgets/__stories__/video.stories.tsx b/packages/perseus/src/widgets/__stories__/video.stories.tsx index eb31c311ff..902e9cbdb9 100644 --- a/packages/perseus/src/widgets/__stories__/video.stories.tsx +++ b/packages/perseus/src/widgets/__stories__/video.stories.tsx @@ -1,7 +1,7 @@ import * as React from "react"; import {RendererWithDebugUI} from "../../../../../testing/renderer-with-debug-ui"; -import {question1} from "../__testdata__/video.testdata"; +import {question1, question2, question3} from "../__testdata__/video.testdata"; export default { title: "Perseus/Widgets/Video", @@ -12,3 +12,11 @@ type StoryArgs = Record; export const Question1 = (args: StoryArgs): React.ReactElement => { return ; }; + +export const Question2 = (args: StoryArgs): React.ReactElement => { + return ; +}; + +export const Question3 = (args: StoryArgs): React.ReactElement => { + return ; +}; diff --git a/packages/perseus/src/widgets/__testdata__/video.testdata.ts b/packages/perseus/src/widgets/__testdata__/video.testdata.ts index 193b933b08..36b2578d42 100644 --- a/packages/perseus/src/widgets/__testdata__/video.testdata.ts +++ b/packages/perseus/src/widgets/__testdata__/video.testdata.ts @@ -19,3 +19,43 @@ export const question1: PerseusRenderer = { }, replace: false, }; + +export const question2: PerseusRenderer = { + content: + "Watch the WMF at Angkor Wat video to find the answer.\n\n[[\u2603 video 1]]\n\n", + images: {}, + widgets: { + "video 1": { + graded: true, + version: {major: 0, minor: 0}, + static: false, + type: "video", + options: { + static: false, + location: "https://player.vimeo.com/video/4754041", + }, + alignment: "block", + }, + }, + replace: false, +}; + +export const question3: PerseusRenderer = { + content: + "Watch the WMF at Angkor Wat video to find the answer.\n\n[[\u2603 video 1]]\n\n", + images: {}, + widgets: { + "video 1": { + graded: true, + version: {major: 0, minor: 0}, + static: false, + type: "video", + options: { + static: false, + location: "https://player.vimeo.com/video/4754041?h=64fbc32a6e", + }, + alignment: "block", + }, + }, + replace: false, +}; diff --git a/packages/perseus/src/widgets/__tests__/video.test.ts b/packages/perseus/src/widgets/__tests__/video.test.ts index 22511fc106..083ace98ea 100644 --- a/packages/perseus/src/widgets/__tests__/video.test.ts +++ b/packages/perseus/src/widgets/__tests__/video.test.ts @@ -2,7 +2,7 @@ import "@testing-library/jest-dom"; import {testDependencies} from "../../../../../testing/test-dependencies"; import * as Dependencies from "../../dependencies"; -import {question1} from "../__testdata__/video.testdata"; +import {question1, question2} from "../__testdata__/video.testdata"; import {renderQuestion} from "./renderQuestion"; @@ -50,4 +50,20 @@ describe("video widget", () => { // Assert expect(container).toMatchSnapshot("first mobile render"); }); + + it("vimeo widget should contain dnt param", () => { + // Arrange + const apiOptions: APIOptions = { + isMobile: false, + }; + + // Act + renderQuestion(question2, apiOptions); + + // Assert + // eslint-disable-next-line testing-library/no-node-access + expect(document.getElementsByTagName("iframe")[0].src).toContain( + "dnt=1", + ); + }); }); diff --git a/packages/perseus/src/widgets/video.tsx b/packages/perseus/src/widgets/video.tsx index 21e24620b0..55cd45aeb9 100644 --- a/packages/perseus/src/widgets/video.tsx +++ b/packages/perseus/src/widgets/video.tsx @@ -24,6 +24,7 @@ const DEFAULT_HEIGHT = 720; const KA_EMBED = "{host}/embed_video?slug={slug}" + "&internal_video_only=1"; const IS_URL = /^https?:\/\//; const IS_KA_SITE = /(khanacademy\.org|localhost)/; +const IS_VIMEO = /(vimeo\.com)/; type UserInput = null; type Rubric = PerseusVideoWidgetOptions; @@ -75,6 +76,16 @@ class Video extends React.Component { if (IS_URL.test(location)) { url = location; + if (IS_VIMEO.test(url)) { + // If this is a vimeo video, we need to add the query string + // parameter "dnt" so that analytics/tracking cookies aren't set. + // https://help.vimeo.com/hc/en-us/articles/12426260232977-Player-parameters-overview + if (url.indexOf("?") === -1) { + url += "?dnt=1"; + } else { + url += "&dnt=1"; + } + } } else { url = KA_EMBED.replace("{slug}", location); let embedHostname = "https://www.khanacademy.org";