Bug 1555507 - Add modal escaping, simple prerendering and bug fixes to Activity Stream r=k88hudson
authorEd Lee <edilee@mozilla.com>
Thu, 30 May 2019 15:04:19 +0000
changeset 476247 07bb612a30b0c2f268a0ffcb50457315de37684e
parent 476246 ce21500c025e1435eb0dc2bdf168674d38a11b1f
child 476248 30ce578fc33cb48b905a57938d8c68144131c212
push id113263
push usernbeleuzu@mozilla.com
push dateFri, 31 May 2019 04:08:20 +0000
treeherdermozilla-inbound@53af18412fd1 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersk88hudson
bugs1555507
milestone69.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1555507 - Add modal escaping, simple prerendering and bug fixes to Activity Stream r=k88hudson Differential Revision: https://phabricator.services.mozilla.com/D33089
.eslintignore
browser/components/newtab/.eslintignore
browser/components/newtab/.mcignore
browser/components/newtab/AboutNewTabService.jsm
browser/components/newtab/bin/render-activity-stream-html.js
browser/components/newtab/common/Actions.jsm
browser/components/newtab/common/PerfService.jsm
browser/components/newtab/common/PrerenderData.jsm
browser/components/newtab/content-src/activity-stream-prerender.jsx
browser/components/newtab/content-src/activity-stream.jsx
browser/components/newtab/content-src/asrouter/asrouter-content.jsx
browser/components/newtab/content-src/asrouter/components/ModalOverlay/ModalOverlay.jsx
browser/components/newtab/content-src/asrouter/components/ModalOverlay/_ModalOverlay.scss
browser/components/newtab/content-src/asrouter/rich-text-strings.js
browser/components/newtab/content-src/asrouter/templates/OnboardingMessage/OnboardingMessage.jsx
browser/components/newtab/content-src/asrouter/templates/OnboardingMessage/_OnboardingMessage.scss
browser/components/newtab/content-src/components/ASRouterAdmin/ASRouterAdmin.jsx
browser/components/newtab/content-src/components/ASRouterAdmin/ASRouterAdmin.scss
browser/components/newtab/content-src/components/Base/Base.jsx
browser/components/newtab/content-src/components/Base/_Base.scss
browser/components/newtab/content-src/components/ContextMenu/ContextMenu.jsx
browser/components/newtab/content-src/components/DiscoveryStreamImpressionStats/_ImpressionStats.scss
browser/components/newtab/content-src/components/TopSites/TopSites.jsx
browser/components/newtab/content-src/lib/init-store.js
browser/components/newtab/css/activity-stream-linux.css
browser/components/newtab/css/activity-stream-mac.css
browser/components/newtab/css/activity-stream-windows.css
browser/components/newtab/data/content/activity-stream.bundle.js
browser/components/newtab/docs/v2-system-addon/data_dictionary.md
browser/components/newtab/docs/v2-system-addon/data_events.md
browser/components/newtab/docs/v2-system-addon/remote_cfr.md
browser/components/newtab/docs/v2-system-addon/telemetry.md
browser/components/newtab/jar.mn
browser/components/newtab/lib/DiscoveryStreamFeed.jsm
browser/components/newtab/lib/PersonalityProvider.jsm
browser/components/newtab/lib/PrefsFeed.jsm
browser/components/newtab/lib/TelemetryFeed.jsm
browser/components/newtab/loaders/inject-loader.js
browser/components/newtab/locales-src/cy/strings.properties
browser/components/newtab/locales-src/lij/strings.properties
browser/components/newtab/locales-src/ro/strings.properties
browser/components/newtab/mochitest.sh
browser/components/newtab/nsIAboutNewTabService.idl
browser/components/newtab/package-lock.json
browser/components/newtab/package.json
browser/components/newtab/prerendered/locales/ach/activity-stream-noscripts.html
browser/components/newtab/prerendered/locales/ach/activity-stream-prerendered-noscripts.html
browser/components/newtab/prerendered/locales/ach/activity-stream-prerendered.html
browser/components/newtab/prerendered/locales/ach/activity-stream.html
browser/components/newtab/prerendered/locales/an/activity-stream-noscripts.html
browser/components/newtab/prerendered/locales/an/activity-stream-prerendered-noscripts.html
browser/components/newtab/prerendered/locales/an/activity-stream-prerendered.html
browser/components/newtab/prerendered/locales/an/activity-stream.html
browser/components/newtab/prerendered/locales/ar/activity-stream-noscripts.html
browser/components/newtab/prerendered/locales/ar/activity-stream-prerendered-noscripts.html
browser/components/newtab/prerendered/locales/ar/activity-stream-prerendered.html
browser/components/newtab/prerendered/locales/ar/activity-stream.html
browser/components/newtab/prerendered/locales/ast/activity-stream-noscripts.html
browser/components/newtab/prerendered/locales/ast/activity-stream-prerendered-noscripts.html
browser/components/newtab/prerendered/locales/ast/activity-stream-prerendered.html
browser/components/newtab/prerendered/locales/ast/activity-stream.html
browser/components/newtab/prerendered/locales/az/activity-stream-noscripts.html
browser/components/newtab/prerendered/locales/az/activity-stream-prerendered-noscripts.html
browser/components/newtab/prerendered/locales/az/activity-stream-prerendered.html
browser/components/newtab/prerendered/locales/az/activity-stream.html
browser/components/newtab/prerendered/locales/be/activity-stream-noscripts.html
browser/components/newtab/prerendered/locales/be/activity-stream-prerendered-noscripts.html
browser/components/newtab/prerendered/locales/be/activity-stream-prerendered.html
browser/components/newtab/prerendered/locales/be/activity-stream.html
browser/components/newtab/prerendered/locales/bg/activity-stream-noscripts.html
browser/components/newtab/prerendered/locales/bg/activity-stream-prerendered-noscripts.html
browser/components/newtab/prerendered/locales/bg/activity-stream-prerendered.html
browser/components/newtab/prerendered/locales/bg/activity-stream.html
browser/components/newtab/prerendered/locales/bn/activity-stream-noscripts.html
browser/components/newtab/prerendered/locales/bn/activity-stream-prerendered-noscripts.html
browser/components/newtab/prerendered/locales/bn/activity-stream-prerendered.html
browser/components/newtab/prerendered/locales/bn/activity-stream.html
browser/components/newtab/prerendered/locales/br/activity-stream-noscripts.html
browser/components/newtab/prerendered/locales/br/activity-stream-prerendered-noscripts.html
browser/components/newtab/prerendered/locales/br/activity-stream-prerendered.html
browser/components/newtab/prerendered/locales/br/activity-stream.html
browser/components/newtab/prerendered/locales/bs/activity-stream-noscripts.html
browser/components/newtab/prerendered/locales/bs/activity-stream-prerendered-noscripts.html
browser/components/newtab/prerendered/locales/bs/activity-stream-prerendered.html
browser/components/newtab/prerendered/locales/bs/activity-stream.html
browser/components/newtab/prerendered/locales/ca/activity-stream-noscripts.html
browser/components/newtab/prerendered/locales/ca/activity-stream-prerendered-noscripts.html
browser/components/newtab/prerendered/locales/ca/activity-stream-prerendered.html
browser/components/newtab/prerendered/locales/ca/activity-stream.html
browser/components/newtab/prerendered/locales/cak/activity-stream-noscripts.html
browser/components/newtab/prerendered/locales/cak/activity-stream-prerendered-noscripts.html
browser/components/newtab/prerendered/locales/cak/activity-stream-prerendered.html
browser/components/newtab/prerendered/locales/cak/activity-stream.html
browser/components/newtab/prerendered/locales/crh/activity-stream-noscripts.html
browser/components/newtab/prerendered/locales/crh/activity-stream-prerendered-noscripts.html
browser/components/newtab/prerendered/locales/crh/activity-stream-prerendered.html
browser/components/newtab/prerendered/locales/crh/activity-stream.html
browser/components/newtab/prerendered/locales/cs/activity-stream-noscripts.html
browser/components/newtab/prerendered/locales/cs/activity-stream-prerendered-noscripts.html
browser/components/newtab/prerendered/locales/cs/activity-stream-prerendered.html
browser/components/newtab/prerendered/locales/cs/activity-stream.html
browser/components/newtab/prerendered/locales/cy/activity-stream-noscripts.html
browser/components/newtab/prerendered/locales/cy/activity-stream-prerendered-noscripts.html
browser/components/newtab/prerendered/locales/cy/activity-stream-prerendered.html
browser/components/newtab/prerendered/locales/cy/activity-stream-strings.js
browser/components/newtab/prerendered/locales/cy/activity-stream.html
browser/components/newtab/prerendered/locales/da/activity-stream-noscripts.html
browser/components/newtab/prerendered/locales/da/activity-stream-prerendered-noscripts.html
browser/components/newtab/prerendered/locales/da/activity-stream-prerendered.html
browser/components/newtab/prerendered/locales/da/activity-stream.html
browser/components/newtab/prerendered/locales/de/activity-stream-noscripts.html
browser/components/newtab/prerendered/locales/de/activity-stream-prerendered-noscripts.html
browser/components/newtab/prerendered/locales/de/activity-stream-prerendered.html
browser/components/newtab/prerendered/locales/de/activity-stream.html
browser/components/newtab/prerendered/locales/dsb/activity-stream-noscripts.html
browser/components/newtab/prerendered/locales/dsb/activity-stream-prerendered-noscripts.html
browser/components/newtab/prerendered/locales/dsb/activity-stream-prerendered.html
browser/components/newtab/prerendered/locales/dsb/activity-stream.html
browser/components/newtab/prerendered/locales/el/activity-stream-noscripts.html
browser/components/newtab/prerendered/locales/el/activity-stream-prerendered-noscripts.html
browser/components/newtab/prerendered/locales/el/activity-stream-prerendered.html
browser/components/newtab/prerendered/locales/el/activity-stream.html
browser/components/newtab/prerendered/locales/en-CA/activity-stream-noscripts.html
browser/components/newtab/prerendered/locales/en-CA/activity-stream-prerendered-noscripts.html
browser/components/newtab/prerendered/locales/en-CA/activity-stream-prerendered.html
browser/components/newtab/prerendered/locales/en-CA/activity-stream.html
browser/components/newtab/prerendered/locales/en-GB/activity-stream-noscripts.html
browser/components/newtab/prerendered/locales/en-GB/activity-stream-prerendered-noscripts.html
browser/components/newtab/prerendered/locales/en-GB/activity-stream-prerendered.html
browser/components/newtab/prerendered/locales/en-GB/activity-stream.html
browser/components/newtab/prerendered/locales/en-US/activity-stream-noscripts.html
browser/components/newtab/prerendered/locales/en-US/activity-stream-prerendered-noscripts.html
browser/components/newtab/prerendered/locales/en-US/activity-stream-prerendered.html
browser/components/newtab/prerendered/locales/en-US/activity-stream.html
browser/components/newtab/prerendered/locales/eo/activity-stream-noscripts.html
browser/components/newtab/prerendered/locales/eo/activity-stream-prerendered-noscripts.html
browser/components/newtab/prerendered/locales/eo/activity-stream-prerendered.html
browser/components/newtab/prerendered/locales/eo/activity-stream.html
browser/components/newtab/prerendered/locales/es-AR/activity-stream-noscripts.html
browser/components/newtab/prerendered/locales/es-AR/activity-stream-prerendered-noscripts.html
browser/components/newtab/prerendered/locales/es-AR/activity-stream-prerendered.html
browser/components/newtab/prerendered/locales/es-AR/activity-stream.html
browser/components/newtab/prerendered/locales/es-CL/activity-stream-noscripts.html
browser/components/newtab/prerendered/locales/es-CL/activity-stream-prerendered-noscripts.html
browser/components/newtab/prerendered/locales/es-CL/activity-stream-prerendered.html
browser/components/newtab/prerendered/locales/es-CL/activity-stream.html
browser/components/newtab/prerendered/locales/es-ES/activity-stream-noscripts.html
browser/components/newtab/prerendered/locales/es-ES/activity-stream-prerendered-noscripts.html
browser/components/newtab/prerendered/locales/es-ES/activity-stream-prerendered.html
browser/components/newtab/prerendered/locales/es-ES/activity-stream.html
browser/components/newtab/prerendered/locales/es-MX/activity-stream-noscripts.html
browser/components/newtab/prerendered/locales/es-MX/activity-stream-prerendered-noscripts.html
browser/components/newtab/prerendered/locales/es-MX/activity-stream-prerendered.html
browser/components/newtab/prerendered/locales/es-MX/activity-stream.html
browser/components/newtab/prerendered/locales/et/activity-stream-noscripts.html
browser/components/newtab/prerendered/locales/et/activity-stream-prerendered-noscripts.html
browser/components/newtab/prerendered/locales/et/activity-stream-prerendered.html
browser/components/newtab/prerendered/locales/et/activity-stream.html
browser/components/newtab/prerendered/locales/eu/activity-stream-noscripts.html
browser/components/newtab/prerendered/locales/eu/activity-stream-prerendered-noscripts.html
browser/components/newtab/prerendered/locales/eu/activity-stream-prerendered.html
browser/components/newtab/prerendered/locales/eu/activity-stream.html
browser/components/newtab/prerendered/locales/fa/activity-stream-noscripts.html
browser/components/newtab/prerendered/locales/fa/activity-stream-prerendered-noscripts.html
browser/components/newtab/prerendered/locales/fa/activity-stream-prerendered.html
browser/components/newtab/prerendered/locales/fa/activity-stream.html
browser/components/newtab/prerendered/locales/ff/activity-stream-noscripts.html
browser/components/newtab/prerendered/locales/ff/activity-stream-prerendered-noscripts.html
browser/components/newtab/prerendered/locales/ff/activity-stream-prerendered.html
browser/components/newtab/prerendered/locales/ff/activity-stream.html
browser/components/newtab/prerendered/locales/fi/activity-stream-noscripts.html
browser/components/newtab/prerendered/locales/fi/activity-stream-prerendered-noscripts.html
browser/components/newtab/prerendered/locales/fi/activity-stream-prerendered.html
browser/components/newtab/prerendered/locales/fi/activity-stream.html
browser/components/newtab/prerendered/locales/fr/activity-stream-noscripts.html
browser/components/newtab/prerendered/locales/fr/activity-stream-prerendered-noscripts.html
browser/components/newtab/prerendered/locales/fr/activity-stream-prerendered.html
browser/components/newtab/prerendered/locales/fr/activity-stream.html
browser/components/newtab/prerendered/locales/fy-NL/activity-stream-noscripts.html
browser/components/newtab/prerendered/locales/fy-NL/activity-stream-prerendered-noscripts.html
browser/components/newtab/prerendered/locales/fy-NL/activity-stream-prerendered.html
browser/components/newtab/prerendered/locales/fy-NL/activity-stream.html
browser/components/newtab/prerendered/locales/ga-IE/activity-stream-noscripts.html
browser/components/newtab/prerendered/locales/ga-IE/activity-stream-prerendered-noscripts.html
browser/components/newtab/prerendered/locales/ga-IE/activity-stream-prerendered.html
browser/components/newtab/prerendered/locales/ga-IE/activity-stream.html
browser/components/newtab/prerendered/locales/gd/activity-stream-noscripts.html
browser/components/newtab/prerendered/locales/gd/activity-stream-prerendered-noscripts.html
browser/components/newtab/prerendered/locales/gd/activity-stream-prerendered.html
browser/components/newtab/prerendered/locales/gd/activity-stream.html
browser/components/newtab/prerendered/locales/gl/activity-stream-noscripts.html
browser/components/newtab/prerendered/locales/gl/activity-stream-prerendered-noscripts.html
browser/components/newtab/prerendered/locales/gl/activity-stream-prerendered.html
browser/components/newtab/prerendered/locales/gl/activity-stream.html
browser/components/newtab/prerendered/locales/gn/activity-stream-noscripts.html
browser/components/newtab/prerendered/locales/gn/activity-stream-prerendered-noscripts.html
browser/components/newtab/prerendered/locales/gn/activity-stream-prerendered.html
browser/components/newtab/prerendered/locales/gn/activity-stream.html
browser/components/newtab/prerendered/locales/gu-IN/activity-stream-noscripts.html
browser/components/newtab/prerendered/locales/gu-IN/activity-stream-prerendered-noscripts.html
browser/components/newtab/prerendered/locales/gu-IN/activity-stream-prerendered.html
browser/components/newtab/prerendered/locales/gu-IN/activity-stream.html
browser/components/newtab/prerendered/locales/he/activity-stream-noscripts.html
browser/components/newtab/prerendered/locales/he/activity-stream-prerendered-noscripts.html
browser/components/newtab/prerendered/locales/he/activity-stream-prerendered.html
browser/components/newtab/prerendered/locales/he/activity-stream.html
browser/components/newtab/prerendered/locales/hi-IN/activity-stream-noscripts.html
browser/components/newtab/prerendered/locales/hi-IN/activity-stream-prerendered-noscripts.html
browser/components/newtab/prerendered/locales/hi-IN/activity-stream-prerendered.html
browser/components/newtab/prerendered/locales/hi-IN/activity-stream.html
browser/components/newtab/prerendered/locales/hr/activity-stream-noscripts.html
browser/components/newtab/prerendered/locales/hr/activity-stream-prerendered-noscripts.html
browser/components/newtab/prerendered/locales/hr/activity-stream-prerendered.html
browser/components/newtab/prerendered/locales/hr/activity-stream.html
browser/components/newtab/prerendered/locales/hsb/activity-stream-noscripts.html
browser/components/newtab/prerendered/locales/hsb/activity-stream-prerendered-noscripts.html
browser/components/newtab/prerendered/locales/hsb/activity-stream-prerendered.html
browser/components/newtab/prerendered/locales/hsb/activity-stream.html
browser/components/newtab/prerendered/locales/hu/activity-stream-noscripts.html
browser/components/newtab/prerendered/locales/hu/activity-stream-prerendered-noscripts.html
browser/components/newtab/prerendered/locales/hu/activity-stream-prerendered.html
browser/components/newtab/prerendered/locales/hu/activity-stream.html
browser/components/newtab/prerendered/locales/hy-AM/activity-stream-noscripts.html
browser/components/newtab/prerendered/locales/hy-AM/activity-stream-prerendered-noscripts.html
browser/components/newtab/prerendered/locales/hy-AM/activity-stream-prerendered.html
browser/components/newtab/prerendered/locales/hy-AM/activity-stream.html
browser/components/newtab/prerendered/locales/ia/activity-stream-noscripts.html
browser/components/newtab/prerendered/locales/ia/activity-stream-prerendered-noscripts.html
browser/components/newtab/prerendered/locales/ia/activity-stream-prerendered.html
browser/components/newtab/prerendered/locales/ia/activity-stream.html
browser/components/newtab/prerendered/locales/id/activity-stream-noscripts.html
browser/components/newtab/prerendered/locales/id/activity-stream-prerendered-noscripts.html
browser/components/newtab/prerendered/locales/id/activity-stream-prerendered.html
browser/components/newtab/prerendered/locales/id/activity-stream.html
browser/components/newtab/prerendered/locales/is/activity-stream-noscripts.html
browser/components/newtab/prerendered/locales/is/activity-stream-prerendered-noscripts.html
browser/components/newtab/prerendered/locales/is/activity-stream-prerendered.html
browser/components/newtab/prerendered/locales/is/activity-stream.html
browser/components/newtab/prerendered/locales/it/activity-stream-noscripts.html
browser/components/newtab/prerendered/locales/it/activity-stream-prerendered-noscripts.html
browser/components/newtab/prerendered/locales/it/activity-stream-prerendered.html
browser/components/newtab/prerendered/locales/it/activity-stream.html
browser/components/newtab/prerendered/locales/ja-JP-mac/activity-stream-noscripts.html
browser/components/newtab/prerendered/locales/ja-JP-mac/activity-stream-prerendered-noscripts.html
browser/components/newtab/prerendered/locales/ja-JP-mac/activity-stream-prerendered.html
browser/components/newtab/prerendered/locales/ja-JP-mac/activity-stream.html
browser/components/newtab/prerendered/locales/ja/activity-stream-noscripts.html
browser/components/newtab/prerendered/locales/ja/activity-stream-prerendered-noscripts.html
browser/components/newtab/prerendered/locales/ja/activity-stream-prerendered.html
browser/components/newtab/prerendered/locales/ja/activity-stream.html
browser/components/newtab/prerendered/locales/ka/activity-stream-noscripts.html
browser/components/newtab/prerendered/locales/ka/activity-stream-prerendered-noscripts.html
browser/components/newtab/prerendered/locales/ka/activity-stream-prerendered.html
browser/components/newtab/prerendered/locales/ka/activity-stream.html
browser/components/newtab/prerendered/locales/kab/activity-stream-noscripts.html
browser/components/newtab/prerendered/locales/kab/activity-stream-prerendered-noscripts.html
browser/components/newtab/prerendered/locales/kab/activity-stream-prerendered.html
browser/components/newtab/prerendered/locales/kab/activity-stream.html
browser/components/newtab/prerendered/locales/kk/activity-stream-noscripts.html
browser/components/newtab/prerendered/locales/kk/activity-stream-prerendered-noscripts.html
browser/components/newtab/prerendered/locales/kk/activity-stream-prerendered.html
browser/components/newtab/prerendered/locales/kk/activity-stream.html
browser/components/newtab/prerendered/locales/km/activity-stream-noscripts.html
browser/components/newtab/prerendered/locales/km/activity-stream-prerendered-noscripts.html
browser/components/newtab/prerendered/locales/km/activity-stream-prerendered.html
browser/components/newtab/prerendered/locales/km/activity-stream.html
browser/components/newtab/prerendered/locales/kn/activity-stream-noscripts.html
browser/components/newtab/prerendered/locales/kn/activity-stream-prerendered-noscripts.html
browser/components/newtab/prerendered/locales/kn/activity-stream-prerendered.html
browser/components/newtab/prerendered/locales/kn/activity-stream.html
browser/components/newtab/prerendered/locales/ko/activity-stream-noscripts.html
browser/components/newtab/prerendered/locales/ko/activity-stream-prerendered-noscripts.html
browser/components/newtab/prerendered/locales/ko/activity-stream-prerendered.html
browser/components/newtab/prerendered/locales/ko/activity-stream.html
browser/components/newtab/prerendered/locales/lij/activity-stream-noscripts.html
browser/components/newtab/prerendered/locales/lij/activity-stream-prerendered-noscripts.html
browser/components/newtab/prerendered/locales/lij/activity-stream-prerendered.html
browser/components/newtab/prerendered/locales/lij/activity-stream-strings.js
browser/components/newtab/prerendered/locales/lij/activity-stream.html
browser/components/newtab/prerendered/locales/lo/activity-stream-noscripts.html
browser/components/newtab/prerendered/locales/lo/activity-stream-prerendered-noscripts.html
browser/components/newtab/prerendered/locales/lo/activity-stream-prerendered.html
browser/components/newtab/prerendered/locales/lo/activity-stream.html
browser/components/newtab/prerendered/locales/lt/activity-stream-noscripts.html
browser/components/newtab/prerendered/locales/lt/activity-stream-prerendered-noscripts.html
browser/components/newtab/prerendered/locales/lt/activity-stream-prerendered.html
browser/components/newtab/prerendered/locales/lt/activity-stream.html
browser/components/newtab/prerendered/locales/ltg/activity-stream-noscripts.html
browser/components/newtab/prerendered/locales/ltg/activity-stream-prerendered-noscripts.html
browser/components/newtab/prerendered/locales/ltg/activity-stream-prerendered.html
browser/components/newtab/prerendered/locales/ltg/activity-stream.html
browser/components/newtab/prerendered/locales/lv/activity-stream-noscripts.html
browser/components/newtab/prerendered/locales/lv/activity-stream-prerendered-noscripts.html
browser/components/newtab/prerendered/locales/lv/activity-stream-prerendered.html
browser/components/newtab/prerendered/locales/lv/activity-stream.html
browser/components/newtab/prerendered/locales/mk/activity-stream-noscripts.html
browser/components/newtab/prerendered/locales/mk/activity-stream-prerendered-noscripts.html
browser/components/newtab/prerendered/locales/mk/activity-stream-prerendered.html
browser/components/newtab/prerendered/locales/mk/activity-stream.html
browser/components/newtab/prerendered/locales/mr/activity-stream-noscripts.html
browser/components/newtab/prerendered/locales/mr/activity-stream-prerendered-noscripts.html
browser/components/newtab/prerendered/locales/mr/activity-stream-prerendered.html
browser/components/newtab/prerendered/locales/mr/activity-stream.html
browser/components/newtab/prerendered/locales/ms/activity-stream-noscripts.html
browser/components/newtab/prerendered/locales/ms/activity-stream-prerendered-noscripts.html
browser/components/newtab/prerendered/locales/ms/activity-stream-prerendered.html
browser/components/newtab/prerendered/locales/ms/activity-stream.html
browser/components/newtab/prerendered/locales/my/activity-stream-noscripts.html
browser/components/newtab/prerendered/locales/my/activity-stream-prerendered-noscripts.html
browser/components/newtab/prerendered/locales/my/activity-stream-prerendered.html
browser/components/newtab/prerendered/locales/my/activity-stream.html
browser/components/newtab/prerendered/locales/nb-NO/activity-stream-noscripts.html
browser/components/newtab/prerendered/locales/nb-NO/activity-stream-prerendered-noscripts.html
browser/components/newtab/prerendered/locales/nb-NO/activity-stream-prerendered.html
browser/components/newtab/prerendered/locales/nb-NO/activity-stream.html
browser/components/newtab/prerendered/locales/ne-NP/activity-stream-noscripts.html
browser/components/newtab/prerendered/locales/ne-NP/activity-stream-prerendered-noscripts.html
browser/components/newtab/prerendered/locales/ne-NP/activity-stream-prerendered.html
browser/components/newtab/prerendered/locales/ne-NP/activity-stream.html
browser/components/newtab/prerendered/locales/nl/activity-stream-noscripts.html
browser/components/newtab/prerendered/locales/nl/activity-stream-prerendered-noscripts.html
browser/components/newtab/prerendered/locales/nl/activity-stream-prerendered.html
browser/components/newtab/prerendered/locales/nl/activity-stream.html
browser/components/newtab/prerendered/locales/nn-NO/activity-stream-noscripts.html
browser/components/newtab/prerendered/locales/nn-NO/activity-stream-prerendered-noscripts.html
browser/components/newtab/prerendered/locales/nn-NO/activity-stream-prerendered.html
browser/components/newtab/prerendered/locales/nn-NO/activity-stream.html
browser/components/newtab/prerendered/locales/oc/activity-stream-noscripts.html
browser/components/newtab/prerendered/locales/oc/activity-stream-prerendered-noscripts.html
browser/components/newtab/prerendered/locales/oc/activity-stream-prerendered.html
browser/components/newtab/prerendered/locales/oc/activity-stream.html
browser/components/newtab/prerendered/locales/pa-IN/activity-stream-noscripts.html
browser/components/newtab/prerendered/locales/pa-IN/activity-stream-prerendered-noscripts.html
browser/components/newtab/prerendered/locales/pa-IN/activity-stream-prerendered.html
browser/components/newtab/prerendered/locales/pa-IN/activity-stream.html
browser/components/newtab/prerendered/locales/pl/activity-stream-noscripts.html
browser/components/newtab/prerendered/locales/pl/activity-stream-prerendered-noscripts.html
browser/components/newtab/prerendered/locales/pl/activity-stream-prerendered.html
browser/components/newtab/prerendered/locales/pl/activity-stream.html
browser/components/newtab/prerendered/locales/pt-BR/activity-stream-noscripts.html
browser/components/newtab/prerendered/locales/pt-BR/activity-stream-prerendered-noscripts.html
browser/components/newtab/prerendered/locales/pt-BR/activity-stream-prerendered.html
browser/components/newtab/prerendered/locales/pt-BR/activity-stream.html
browser/components/newtab/prerendered/locales/pt-PT/activity-stream-noscripts.html
browser/components/newtab/prerendered/locales/pt-PT/activity-stream-prerendered-noscripts.html
browser/components/newtab/prerendered/locales/pt-PT/activity-stream-prerendered.html
browser/components/newtab/prerendered/locales/pt-PT/activity-stream.html
browser/components/newtab/prerendered/locales/rm/activity-stream-noscripts.html
browser/components/newtab/prerendered/locales/rm/activity-stream-prerendered-noscripts.html
browser/components/newtab/prerendered/locales/rm/activity-stream-prerendered.html
browser/components/newtab/prerendered/locales/rm/activity-stream.html
browser/components/newtab/prerendered/locales/ro/activity-stream-noscripts.html
browser/components/newtab/prerendered/locales/ro/activity-stream-prerendered-noscripts.html
browser/components/newtab/prerendered/locales/ro/activity-stream-prerendered.html
browser/components/newtab/prerendered/locales/ro/activity-stream-strings.js
browser/components/newtab/prerendered/locales/ro/activity-stream.html
browser/components/newtab/prerendered/locales/ru/activity-stream-noscripts.html
browser/components/newtab/prerendered/locales/ru/activity-stream-prerendered-noscripts.html
browser/components/newtab/prerendered/locales/ru/activity-stream-prerendered.html
browser/components/newtab/prerendered/locales/ru/activity-stream.html
browser/components/newtab/prerendered/locales/si/activity-stream-noscripts.html
browser/components/newtab/prerendered/locales/si/activity-stream-prerendered-noscripts.html
browser/components/newtab/prerendered/locales/si/activity-stream-prerendered.html
browser/components/newtab/prerendered/locales/si/activity-stream.html
browser/components/newtab/prerendered/locales/sk/activity-stream-noscripts.html
browser/components/newtab/prerendered/locales/sk/activity-stream-prerendered-noscripts.html
browser/components/newtab/prerendered/locales/sk/activity-stream-prerendered.html
browser/components/newtab/prerendered/locales/sk/activity-stream.html
browser/components/newtab/prerendered/locales/sl/activity-stream-noscripts.html
browser/components/newtab/prerendered/locales/sl/activity-stream-prerendered-noscripts.html
browser/components/newtab/prerendered/locales/sl/activity-stream-prerendered.html
browser/components/newtab/prerendered/locales/sl/activity-stream.html
browser/components/newtab/prerendered/locales/sq/activity-stream-noscripts.html
browser/components/newtab/prerendered/locales/sq/activity-stream-prerendered-noscripts.html
browser/components/newtab/prerendered/locales/sq/activity-stream-prerendered.html
browser/components/newtab/prerendered/locales/sq/activity-stream.html
browser/components/newtab/prerendered/locales/sr/activity-stream-noscripts.html
browser/components/newtab/prerendered/locales/sr/activity-stream-prerendered-noscripts.html
browser/components/newtab/prerendered/locales/sr/activity-stream-prerendered.html
browser/components/newtab/prerendered/locales/sr/activity-stream.html
browser/components/newtab/prerendered/locales/sv-SE/activity-stream-noscripts.html
browser/components/newtab/prerendered/locales/sv-SE/activity-stream-prerendered-noscripts.html
browser/components/newtab/prerendered/locales/sv-SE/activity-stream-prerendered.html
browser/components/newtab/prerendered/locales/sv-SE/activity-stream.html
browser/components/newtab/prerendered/locales/ta/activity-stream-noscripts.html
browser/components/newtab/prerendered/locales/ta/activity-stream-prerendered-noscripts.html
browser/components/newtab/prerendered/locales/ta/activity-stream-prerendered.html
browser/components/newtab/prerendered/locales/ta/activity-stream.html
browser/components/newtab/prerendered/locales/te/activity-stream-noscripts.html
browser/components/newtab/prerendered/locales/te/activity-stream-prerendered-noscripts.html
browser/components/newtab/prerendered/locales/te/activity-stream-prerendered.html
browser/components/newtab/prerendered/locales/te/activity-stream.html
browser/components/newtab/prerendered/locales/th/activity-stream-noscripts.html
browser/components/newtab/prerendered/locales/th/activity-stream-prerendered-noscripts.html
browser/components/newtab/prerendered/locales/th/activity-stream-prerendered.html
browser/components/newtab/prerendered/locales/th/activity-stream.html
browser/components/newtab/prerendered/locales/tl/activity-stream-noscripts.html
browser/components/newtab/prerendered/locales/tl/activity-stream-prerendered-noscripts.html
browser/components/newtab/prerendered/locales/tl/activity-stream-prerendered.html
browser/components/newtab/prerendered/locales/tl/activity-stream.html
browser/components/newtab/prerendered/locales/tr/activity-stream-noscripts.html
browser/components/newtab/prerendered/locales/tr/activity-stream-prerendered-noscripts.html
browser/components/newtab/prerendered/locales/tr/activity-stream-prerendered.html
browser/components/newtab/prerendered/locales/tr/activity-stream.html
browser/components/newtab/prerendered/locales/trs/activity-stream-noscripts.html
browser/components/newtab/prerendered/locales/trs/activity-stream-prerendered-noscripts.html
browser/components/newtab/prerendered/locales/trs/activity-stream-prerendered.html
browser/components/newtab/prerendered/locales/trs/activity-stream.html
browser/components/newtab/prerendered/locales/uk/activity-stream-noscripts.html
browser/components/newtab/prerendered/locales/uk/activity-stream-prerendered-noscripts.html
browser/components/newtab/prerendered/locales/uk/activity-stream-prerendered.html
browser/components/newtab/prerendered/locales/uk/activity-stream.html
browser/components/newtab/prerendered/locales/ur/activity-stream-noscripts.html
browser/components/newtab/prerendered/locales/ur/activity-stream-prerendered-noscripts.html
browser/components/newtab/prerendered/locales/ur/activity-stream-prerendered.html
browser/components/newtab/prerendered/locales/ur/activity-stream.html
browser/components/newtab/prerendered/locales/uz/activity-stream-noscripts.html
browser/components/newtab/prerendered/locales/uz/activity-stream-prerendered-noscripts.html
browser/components/newtab/prerendered/locales/uz/activity-stream-prerendered.html
browser/components/newtab/prerendered/locales/uz/activity-stream.html
browser/components/newtab/prerendered/locales/vi/activity-stream-noscripts.html
browser/components/newtab/prerendered/locales/vi/activity-stream-prerendered-noscripts.html
browser/components/newtab/prerendered/locales/vi/activity-stream-prerendered.html
browser/components/newtab/prerendered/locales/vi/activity-stream.html
browser/components/newtab/prerendered/locales/zh-CN/activity-stream-noscripts.html
browser/components/newtab/prerendered/locales/zh-CN/activity-stream-prerendered-noscripts.html
browser/components/newtab/prerendered/locales/zh-CN/activity-stream-prerendered.html
browser/components/newtab/prerendered/locales/zh-CN/activity-stream.html
browser/components/newtab/prerendered/locales/zh-TW/activity-stream-noscripts.html
browser/components/newtab/prerendered/locales/zh-TW/activity-stream-prerendered-noscripts.html
browser/components/newtab/prerendered/locales/zh-TW/activity-stream-prerendered.html
browser/components/newtab/prerendered/locales/zh-TW/activity-stream.html
browser/components/newtab/prerendered/static/activity-stream-debug.html
browser/components/newtab/prerendered/static/activity-stream-initial-state.js
browser/components/newtab/prerendered/static/activity-stream-prerendered-debug.html
browser/components/newtab/test/browser/browser_packaged_as_locales.js
browser/components/newtab/test/browser/browser_topsites_section.js
browser/components/newtab/test/schemas/pings.js
browser/components/newtab/test/unit/activity-stream-prerender.test.jsx
browser/components/newtab/test/unit/common/PrerenderData.test.js
browser/components/newtab/test/unit/content-src/lib/init-store.test.js
browser/components/newtab/test/unit/lib/PrefsFeed.test.js
browser/components/newtab/test/unit/lib/TelemetryFeed.test.js
browser/components/newtab/test/xpcshell/test_AboutNewTabService.js
browser/components/newtab/webpack.prerender.config.js
browser/components/newtab/yamscripts.yml
--- a/.eslintignore
+++ b/.eslintignore
@@ -52,17 +52,16 @@ browser/extensions/screenshots/**
 browser/extensions/pdfjs/content/build**
 browser/extensions/pdfjs/content/web**
 # generated or library files in pocket
 browser/components/pocket/content/panels/js/tmpl.js
 browser/components/pocket/content/panels/js/vendor/**
 
 # Ignore newtab files
 # Kept in sync with browser/components/newtab/.eslintignore
-browser/components/newtab/bin/prerender.js
 browser/components/newtab/data/
 browser/components/newtab/logs/
 browser/components/newtab/prerendered/
 browser/components/newtab/vendor/
 
 # The only file in browser/locales/ is pre-processed.
 browser/locales/**
 # imported from chromium
--- a/browser/components/newtab/.eslintignore
+++ b/browser/components/newtab/.eslintignore
@@ -1,5 +1,4 @@
-bin/prerender.js                                                                                       
-data/                                                                                                  
-logs/                                                                                                  
-prerendered/                                                                                           
+data/
+logs/
+prerendered/
 vendor/
--- a/browser/components/newtab/.mcignore
+++ b/browser/components/newtab/.mcignore
@@ -2,18 +2,16 @@ npm-debug.log
 .DS_Store
 *.sw[po]
 *.xpi
 *.pyc
 *.update.rdf
 .gitignore
 
 /.git/
-/bin/prerender.js
-/bin/prerender.js.map
 /data/locales.json
 /dist/
 /logs/
 /node_modules/
 
 # ignore README since it's GitHub specific
 /README.md
 
--- a/browser/components/newtab/AboutNewTabService.jsm
+++ b/browser/components/newtab/AboutNewTabService.jsm
@@ -26,24 +26,22 @@ const BASE_URL = "resource://activity-st
 const ACTIVITY_STREAM_PAGES = new Set(["home", "newtab", "welcome"]);
 
 const IS_MAIN_PROCESS = Services.appinfo.processType === Services.appinfo.PROCESS_TYPE_DEFAULT;
 const IS_PRIVILEGED_PROCESS = Services.appinfo.remoteType === E10SUtils.PRIVILEGEDABOUT_REMOTE_TYPE;
 
 const IS_RELEASE_OR_BETA = AppConstants.RELEASE_OR_BETA;
 
 const PREF_SEPARATE_PRIVILEGEDABOUT_CONTENT_PROCESS = "browser.tabs.remote.separatePrivilegedContentProcess";
-const PREF_ACTIVITY_STREAM_PRERENDER_ENABLED = "browser.newtabpage.activity-stream.prerender";
 const PREF_ACTIVITY_STREAM_DEBUG = "browser.newtabpage.activity-stream.debug";
 
 function AboutNewTabService() {
   Services.obs.addObserver(this, TOPIC_APP_QUIT);
   Services.obs.addObserver(this, TOPIC_LOCALES_CHANGE);
   Services.prefs.addObserver(PREF_SEPARATE_PRIVILEGEDABOUT_CONTENT_PROCESS, this);
-  Services.prefs.addObserver(PREF_ACTIVITY_STREAM_PRERENDER_ENABLED, this);
   if (!IS_RELEASE_OR_BETA) {
     Services.prefs.addObserver(PREF_ACTIVITY_STREAM_DEBUG, this);
   }
 
   // More initialization happens here
   this.toggleActivityStream(true);
   this.initialized = true;
   this.alreadyRecordedTopsitesPainted = false;
@@ -85,17 +83,16 @@ function AboutNewTabService() {
  * Loading a chrome resource, or an about: URL in the redirector with either the
  * LOAD_NORMAL or LOAD_REPLACE flags yield unexpected behaviors, so a roundtrip
  * to the redirector from browser chrome is avoided.
  */
 AboutNewTabService.prototype = {
 
   _newTabURL: ABOUT_URL,
   _activityStreamEnabled: false,
-  _activityStreamPrerender: false,
   _activityStreamPath: "",
   _activityStreamDebug: false,
   _privilegedAboutContentProcess: false,
   _overridden: false,
   willNotifyUser: false,
 
   classID: Components.ID("{dfcd2adc-7867-4d3a-ba70-17501f208142}"),
   QueryInterface: ChromeUtils.generateQI([
@@ -105,19 +102,16 @@ AboutNewTabService.prototype = {
 
   observe(subject, topic, data) {
     switch (topic) {
       case "nsPref:changed":
         if (data === PREF_SEPARATE_PRIVILEGEDABOUT_CONTENT_PROCESS) {
           this._privilegedAboutContentProcess = Services.prefs.getBoolPref(PREF_SEPARATE_PRIVILEGEDABOUT_CONTENT_PROCESS);
           this.updatePrerenderedPath();
           this.notifyChange();
-        } else if (data === PREF_ACTIVITY_STREAM_PRERENDER_ENABLED) {
-          this._activityStreamPrerender = Services.prefs.getBoolPref(PREF_ACTIVITY_STREAM_PRERENDER_ENABLED);
-          this.notifyChange();
         } else if (!IS_RELEASE_OR_BETA && data === PREF_ACTIVITY_STREAM_DEBUG) {
           this._activityStreamDebug = Services.prefs.getBoolPref(PREF_ACTIVITY_STREAM_DEBUG, false);
           this.updatePrerenderedPath();
           this.notifyChange();
         }
         break;
       case TOPIC_CONTENT_DOCUMENT_INTERACTIVE: {
         const win = subject.defaultView;
@@ -153,20 +147,16 @@ AboutNewTabService.prototype = {
             `${BASE_URL}vendor/prop-types.js`,
             `${BASE_URL}vendor/react-intl.js`,
             `${BASE_URL}vendor/redux.js`,
             `${BASE_URL}vendor/react-redux.js`,
             `${BASE_URL}prerendered/${this.activityStreamLocale}/activity-stream-strings.js`,
             `${BASE_URL}data/content/activity-stream.bundle.js`,
           ];
 
-          if (this._activityStreamPrerender) {
-            scripts.unshift(`${BASE_URL}prerendered/static/activity-stream-initial-state.js`);
-          }
-
           for (let script of scripts) {
             Services.scriptloader.loadSubScript(script, win); // Synchronous call
           }
         };
         subject.addEventListener("DOMContentLoaded", onLoaded, {once: true});
 
         // There is a possibility that DOMContentLoaded won't be fired. This
         // unload event (which cannot be cancelled) will attempt to remove
@@ -212,17 +202,16 @@ AboutNewTabService.prototype = {
       return false;
     }
     if (stateEnabled) {
       this._activityStreamEnabled = true;
     } else {
       this._activityStreamEnabled = false;
     }
     this._privilegedAboutContentProcess = Services.prefs.getBoolPref(PREF_SEPARATE_PRIVILEGEDABOUT_CONTENT_PROCESS);
-    this._activityStreamPrerender = Services.prefs.getBoolPref(PREF_ACTIVITY_STREAM_PRERENDER_ENABLED);
     if (!IS_RELEASE_OR_BETA) {
       this._activityStreamDebug = Services.prefs.getBoolPref(PREF_ACTIVITY_STREAM_DEBUG, false);
     }
     this.updatePrerenderedPath();
     this._newtabURL = ABOUT_URL;
     return true;
   },
 
@@ -240,42 +229,35 @@ AboutNewTabService.prototype = {
    * Returns the default URL.
    *
    * This URL depends on various activity stream prefs and locales. Overriding
    * the newtab page has no effect on the result of this function.
    */
   get defaultURL() {
     // Generate the desired activity stream resource depending on state, e.g.,
     // resource://activity-stream/prerendered/ar/activity-stream.html
-    // resource://activity-stream/prerendered/en-US/activity-stream-prerendered.html
     // resource://activity-stream/prerendered/static/activity-stream-debug.html
     return [
       "resource://activity-stream/prerendered/",
       this._activityStreamPath,
       "activity-stream",
-      this._activityStreamPrerender ? "-prerendered" : "",
       // Debug version loads dev scripts but noscripts separately loads scripts
       this._activityStreamDebug && !this._privilegedAboutContentProcess ? "-debug" : "",
       this._privilegedAboutContentProcess ? "-noscripts" : "",
       ".html",
     ].join("");
   },
 
   /*
    * Returns the about:welcome URL
    *
-   * This is calculated in the same way the default URL is, except that we don't
-   * allow prerendering.
+   * This is calculated in the same way the default URL is.
    */
   get welcomeURL() {
-    const prerenderEnabled = this._activityStreamPrerender;
-    this._activityStreamPrerender = false;
-    const url = this.defaultURL;
-    this._activityStreamPrerender = prerenderEnabled;
-    return url;
+    return this.defaultURL;
   },
 
   get newTabURL() {
     return this._newTabURL;
   },
 
   set newTabURL(aNewTabURL) {
     let newTabURL = aNewTabURL.trim();
@@ -296,20 +278,16 @@ AboutNewTabService.prototype = {
   get overridden() {
     return this._overridden;
   },
 
   get activityStreamEnabled() {
     return this._activityStreamEnabled;
   },
 
-  get activityStreamPrerender() {
-    return this._activityStreamPrerender;
-  },
-
   get activityStreamDebug() {
     return this._activityStreamDebug;
   },
 
   get activityStreamLocale() {
     // Pick the best available locale to match the app locales
     return Services.locale.negotiateLanguages(
       // Fix up incorrect BCP47 that are actually lang tags as a workaround for
@@ -347,17 +325,16 @@ AboutNewTabService.prototype = {
 
   uninit() {
     if (!this.initialized) {
       return;
     }
     Services.obs.removeObserver(this, TOPIC_APP_QUIT);
     Services.obs.removeObserver(this, TOPIC_LOCALES_CHANGE);
     Services.prefs.removeObserver(PREF_SEPARATE_PRIVILEGEDABOUT_CONTENT_PROCESS, this);
-    Services.prefs.removeObserver(PREF_ACTIVITY_STREAM_PRERENDER_ENABLED, this);
     if (!IS_RELEASE_OR_BETA) {
       Services.prefs.removeObserver(PREF_ACTIVITY_STREAM_DEBUG, this);
     }
     this.initialized = false;
   },
 };
 
 const EXPORTED_SYMBOLS = ["AboutNewTabService"];
--- a/browser/components/newtab/bin/render-activity-stream-html.js
+++ b/browser/components/newtab/bin/render-activity-stream-html.js
@@ -1,16 +1,13 @@
  /* eslint-disable no-console */
 const fs = require("fs");
 const {mkdir} = require("shelljs");
 const path = require("path");
 
-// Note: this file is generated by webpack from content-src/activity-stream-prerender.jsx
-const {prerender} = require("./prerender");
-
 const {CENTRAL_LOCALES, DEFAULT_LOCALE} = require("./locales");
 
 // Note: DEFAULT_OPTIONS.baseUrl should match BASE_URL in aboutNewTabService.js
 //       in mozilla-central.
 const DEFAULT_OPTIONS = {
   addonPath: "..",
   baseUrl: "resource://activity-stream/",
 };
@@ -59,54 +56,49 @@ function getTextDirection(locale) {
  * prerendered HTML if necessary.
  *
  * @param  {obj} options
  *         {str} options.locale         The locale to render in lang="" attribute
  *         {str} options.direction      The language direction to render in dir="" attribute
  *         {str} options.baseUrl        The base URL for all local assets
  *         {bool} options.debug         Should we use dev versions of JS libraries?
  *         {bool} options.noscripts     Should we include scripts in the prerendered files?
- * @param  {str} html    The prerendered HTML created with React.renderToString (optional)
  * @return {str}         An HTML document as a string
  */
-function templateHTML(options, html) {
-  const isPrerendered = !!html;
+function templateHTML(options) {
   const debugString = options.debug ? "-dev" : "";
   const scripts = [
     "chrome://browser/content/contentSearchUI.js",
     "chrome://browser/content/contentTheme.js",
     `${options.baseUrl}vendor/react${debugString}.js`,
     `${options.baseUrl}vendor/react-dom${debugString}.js`,
     `${options.baseUrl}vendor/prop-types.js`,
     `${options.baseUrl}vendor/react-intl.js`,
     `${options.baseUrl}vendor/redux.js`,
     `${options.baseUrl}vendor/react-redux.js`,
     `${options.baseUrl}prerendered/${options.locale}/activity-stream-strings.js`,
     `${options.baseUrl}data/content/activity-stream.bundle.js`,
   ];
-  if (isPrerendered) {
-    scripts.unshift(`${options.baseUrl}prerendered/static/activity-stream-initial-state.js`);
-  }
 
   // Add spacing and script tags
   const scriptRender = `\n${scripts.map(script => `    <script src="${script}"></script>`).join("\n")}`;
 
   return `<!doctype html>
 <html lang="${options.locale}" dir="${options.direction}">
   <head>
     <meta charset="utf-8">
     <meta http-equiv="Content-Security-Policy" content="default-src 'none'; object-src 'none'; script-src resource: chrome:; connect-src https:; img-src https: data: blob:; style-src 'unsafe-inline';">
     <title>${options.strings.newtab_page_title}</title>
     <link rel="icon" type="image/png" href="chrome://branding/content/icon32.png"/>
     <link rel="stylesheet" href="chrome://browser/content/contentSearchUI.css" />
     <link rel="stylesheet" href="${options.baseUrl}css/activity-stream.css" />
   </head>
   <body class="activity-stream">
     <div id="header-asrouter-container" role="presentation"></div>
-    <div id="root">${isPrerendered ? html : "<!-- Regular React Rendering -->"}</div>
+    <div id="root"></div>
     <div id="footer-asrouter-container" role="presentation"></div>${options.noscripts ? "" : scriptRender}
   </body>
 </html>
 `;
 }
 
 /**
  * templateJs - Generates a js file that passes the initial state of the prerendered
@@ -130,35 +122,30 @@ window.${name} = ${JSON.stringify(state,
 
 /**
  * writeFiles - Writes to the desired files the result of a template given
  * various prerendered data and options.
  *
  * @param {string} name          Something to identify in the console
  * @param {string} destPath      Path to write the files to
  * @param {Map}    filesMap      Mapping of a string file name to templater
- * @param {Object} prerenderData Contains the html and state
  * @param {Object} options       Various options for the templater
  */
-function writeFiles(name, destPath, filesMap, {html, state}, options) {
+function writeFiles(name, destPath, filesMap, options) {
   for (const [file, templater] of filesMap) {
-    fs.writeFileSync(path.join(destPath, file), templater({html, options, state}));
+    fs.writeFileSync(path.join(destPath, file), templater({options}));
   }
   console.log("\x1b[32m", `✓ ${name}`, "\x1b[0m");
 }
 
 const STATIC_FILES = new Map([
   ["activity-stream-debug.html", ({options}) => templateHTML(options)],
-  ["activity-stream-initial-state.js", ({state}) => templateJs("gActivityStreamPrerenderedState", "static", state)],
-  ["activity-stream-prerendered-debug.html", ({html, options}) => templateHTML(options, html)],
 ]);
 
 const LOCALIZED_FILES = new Map([
-  ["activity-stream-prerendered.html", ({html, options}) => templateHTML(options, html)],
-  ["activity-stream-prerendered-noscripts.html", ({html, options}) => templateHTML(Object.assign({}, options, {noscripts: true}), html)],
   ["activity-stream-strings.js", ({options: {locale, strings}}) => templateJs("gActivityStreamStrings", locale, strings)],
   ["activity-stream.html", ({options}) => templateHTML(options)],
   ["activity-stream-noscripts.html", ({options}) => templateHTML(Object.assign({}, options, {noscripts: true}))],
 ]);
 
 /**
  * main - Parses command line arguments, generates html and js with templates,
  *        and writes files to their specified locations.
@@ -195,33 +182,32 @@ function main() { // eslint-disable-line
   for (const locale of [DEFAULT_LOCALE, ...CENTRAL_LOCALES]) {
     // Skip the locale if it would have resulted in duplicate packaged files
     const strings = getStrings(locale, allStrings);
     if (isSubset(strings, defaultStrings) || isSubset(strings, langStrings)) {
       skippedLocales.push(locale);
       continue;
     }
 
-    const prerenderData  = prerender(locale, strings);
     const options = Object.assign({}, baseOptions, {
       direction: getTextDirection(locale),
       locale,
       strings,
     });
 
     // Put locale-specific files in their own directory
     const localePath = path.join(prerenderedPath, "locales", locale);
     mkdir("-p", localePath);
-    writeFiles(locale, localePath, LOCALIZED_FILES, prerenderData, options);
+    writeFiles(locale, localePath, LOCALIZED_FILES, options);
 
     // Only write static files once for the default locale
     if (locale === DEFAULT_LOCALE) {
       const staticPath = path.join(prerenderedPath, "static");
       mkdir("-p", staticPath);
-      writeFiles(`${locale} (static)`, staticPath, STATIC_FILES, prerenderData,
+      writeFiles(`${locale} (static)`, staticPath, STATIC_FILES,
         Object.assign({}, options, {debug: true}));
 
       // Save the default strings to compare against other locales' strings
       defaultStrings = strings;
     }
 
     // Save the language's strings to maybe reuse for the next similar locales
     if (getLanguage(locale) === locale) {
--- a/browser/components/newtab/common/Actions.jsm
+++ b/browser/components/newtab/common/Actions.jsm
@@ -67,17 +67,16 @@ for (const type of [
   "NEW_TAB_REHYDRATED",
   "NEW_TAB_STATE_REQUEST",
   "NEW_TAB_UNLOAD",
   "OPEN_DOWNLOAD_FILE",
   "OPEN_LINK",
   "OPEN_NEW_WINDOW",
   "OPEN_PRIVATE_WINDOW",
   "OPEN_WEBEXT_SETTINGS",
-  "PAGE_PRERENDERED",
   "PLACES_BOOKMARK_ADDED",
   "PLACES_BOOKMARK_REMOVED",
   "PLACES_HISTORY_CLEARED",
   "PLACES_LINKS_CHANGED",
   "PLACES_LINK_BLOCKED",
   "PLACES_LINK_DELETED",
   "PLACES_SAVED_TO_POCKET",
   "POCKET_CTA",
--- a/browser/components/newtab/common/PerfService.jsm
+++ b/browser/components/newtab/common/PerfService.jsm
@@ -10,27 +10,20 @@ if (typeof ChromeUtils !== "undefined") 
 let usablePerfObj;
 
 /* istanbul ignore else */
 // eslint-disable-next-line block-scoped-var
 if (typeof Services !== "undefined") {
   // Borrow the high-resolution timer from the hidden window....
   // eslint-disable-next-line block-scoped-var
   usablePerfObj = Services.appShell.hiddenDOMWindow.performance;
-} else if (typeof performance !== "undefined") {
+} else {
   // we must be running in content space
   // eslint-disable-next-line no-undef
   usablePerfObj = performance;
-} else {
-  // This is a dummy object so this file doesn't crash in the node prerendering
-  // task.
-  usablePerfObj = {
-    now() {},
-    mark() {},
-  };
 }
 
 function _PerfService(options) {
   // For testing, so that we can use a fake Window.performance object with
   // known state.
   if (options && options.performanceObj) {
     this._perf = options.performanceObj;
   } else {
deleted file mode 100644
--- a/browser/components/newtab/common/PrerenderData.jsm
+++ /dev/null
@@ -1,126 +0,0 @@
-class _PrerenderData {
-  constructor(options) {
-    this.initialPrefs = options.initialPrefs;
-    this.initialSections = options.initialSections;
-    this._setValidation(options.validation);
-  }
-
-  get validation() {
-    return this._validation;
-  }
-
-  set validation(value) {
-    this._setValidation(value);
-  }
-
-  get invalidatingPrefs() {
-    return this._invalidatingPrefs;
-  }
-
-    // This is needed so we can use it in the constructor
-  _setValidation(value = []) {
-    this._validation = value;
-    this._invalidatingPrefs = value.reduce((result, next) => {
-      if (typeof next === "string") {
-        result.push(next);
-        return result;
-      } else if (next && next.oneOf) {
-        return result.concat(next.oneOf);
-      } else if (next && next.indexedDB) {
-        return result.concat(next.indexedDB);
-      } else if (next && next.jsonPrefs) {
-        return result.concat(next.jsonPrefs);
-      }
-      throw new Error("Your validation configuration is not properly configured");
-    }, []);
-  }
-
-  _isPrefEnabled(prefObj) {
-    try {
-      let data = JSON.parse(prefObj);
-      return (data && data.enabled) ? true : false; // eslint-disable-line no-unneeded-ternary
-    } catch (e) {
-      return false;
-    }
-  }
-
-  arePrefsValid(getPref, indexedDBPrefs) {
-    for (const prefs of this.validation) {
-      // {oneOf: ["foo", "bar"]}
-      if (prefs && prefs.oneOf && !prefs.oneOf.some(name => getPref(name) === this.initialPrefs[name])) {
-        return false;
-
-        // {indexedDB: ["foo", "bar"]}
-      } else if (indexedDBPrefs && prefs && prefs.indexedDB) {
-        const anyModifiedPrefs = prefs.indexedDB.some(prefName => indexedDBPrefs.some(pref => pref && pref[prefName]));
-        if (anyModifiedPrefs) {
-          return false;
-        }
-        // {jsonPrefs: ["foo", "bar"]}
-      } else if (prefs && prefs.jsonPrefs) {
-        const isPrefModified =
-          prefs.jsonPrefs.some(name => this._isPrefEnabled(getPref(name)) !== this.initialPrefs[name].enabled);
-        if (isPrefModified) {
-          return false;
-        }
-        // "foo"
-      } else if (getPref(prefs) !== this.initialPrefs[prefs]) {
-        return false;
-      }
-    }
-    return true;
-  }
-}
-
-this.PrerenderData = new _PrerenderData({
-  initialPrefs: {
-    "feeds.topsites": true,
-    "showSearch": true,
-    "topSitesRows": 1,
-    "feeds.section.topstories": true,
-    "feeds.section.highlights": true,
-    "sectionOrder": "topsites,topstories,highlights",
-    "collapsed": false,
-    "discoverystream.config": {"enabled": false},
-  },
-  // Prefs listed as invalidating will prevent the prerendered version
-  // of AS from being used if their value is something other than what is listed
-  // here. This is required because some preferences cause the page layout to be
-  // too different for the prerendered version to be used. Unfortunately, this
-  // will result in users who have modified some of their preferences not being
-  // able to get the benefits of prerendering.
-  validation: [
-    "feeds.topsites",
-    "showSearch",
-    "topSitesRows",
-    "sectionOrder",
-    // This means if either of these are set to their default values,
-    // prerendering can be used.
-    {oneOf: ["feeds.section.topstories", "feeds.section.highlights"]},
-    // If any component has the following preference set to `true` it will
-    // invalidate the prerendered version.
-    {indexedDB: ["collapsed"]},
-    // For below prefs, parse value to check enabled property. If enabled property
-    // differs from initial prefs enabled value, prerendering cannot be used
-    {jsonPrefs: ["discoverystream.config"]},
-  ],
-  initialSections: [
-    {
-      enabled: true,
-      icon: "pocket",
-      id: "topstories",
-      order: 1,
-      title: {id: "header_recommended_by", values: {provider: "Pocket"}},
-    },
-    {
-      enabled: true,
-      id: "highlights",
-      icon: "highlights",
-      order: 2,
-      title: {id: "header_highlights"},
-    },
-  ],
-});
-
-this._PrerenderData = _PrerenderData;
-const EXPORTED_SYMBOLS = ["PrerenderData", "_PrerenderData"];
deleted file mode 100644
--- a/browser/components/newtab/content-src/activity-stream-prerender.jsx
+++ /dev/null
@@ -1,45 +0,0 @@
-import {INITIAL_STATE, reducers} from "common/Reducers.jsm";
-import {actionTypes as at} from "common/Actions.jsm";
-import {Base} from "content-src/components/Base/Base";
-import {initStore} from "content-src/lib/init-store";
-import {PrerenderData} from "common/PrerenderData.jsm";
-import {Provider} from "react-redux";
-import React from "react";
-import ReactDOMServer from "react-dom/server";
-
-/**
- * prerenderStore - Generate a store with the initial state required for a prerendered page
- *
- * @return {obj}         A store
- */
-export function prerenderStore() {
-  const store = initStore(reducers, INITIAL_STATE);
-  store.dispatch({type: at.PREFS_INITIAL_VALUES, data: PrerenderData.initialPrefs});
-  PrerenderData.initialSections.forEach(data => store.dispatch({type: at.SECTION_REGISTER, data}));
-  return store;
-}
-
-export function prerender(locale, strings,
-                          renderToString = ReactDOMServer.renderToString) {
-  const store = prerenderStore();
-
-  const html = renderToString(
-    <Provider store={store}>
-      <Base
-        isPrerendered={true}
-        locale={locale}
-        strings={strings} />
-    </Provider>);
-
-  // If this happens, it means pre-rendering is effectively disabled, so we
-  // need to sound the alarms:
-  if (!html || !html.length) {
-    throw new Error("no HTML returned");
-  }
-
-  return {
-    html,
-    state: store.getState(),
-    store,
-  };
-}
--- a/browser/components/newtab/content-src/activity-stream.jsx
+++ b/browser/components/newtab/content-src/activity-stream.jsx
@@ -2,26 +2,20 @@ import {actionCreators as ac, actionType
 import {Base} from "content-src/components/Base/Base";
 import {DetectUserSessionStart} from "content-src/lib/detect-user-session-start";
 import {initStore} from "content-src/lib/init-store";
 import {Provider} from "react-redux";
 import React from "react";
 import ReactDOM from "react-dom";
 import {reducers} from "common/Reducers.jsm";
 
-const store = initStore(reducers, global.gActivityStreamPrerenderedState);
+const store = initStore(reducers);
 
 new DetectUserSessionStart(store).sendEventOrAddListener();
 
-// If we are starting in a prerendered state, we must wait until the first render
-// to request state rehydration (see Base.jsx). If we are NOT in a prerendered state,
-// we can request it immedately.
-if (!global.gActivityStreamPrerenderedState) {
-  store.dispatch(ac.AlsoToMain({type: at.NEW_TAB_STATE_REQUEST}));
-}
+store.dispatch(ac.AlsoToMain({type: at.NEW_TAB_STATE_REQUEST}));
 
 ReactDOM.hydrate(<Provider store={store}>
   <Base
     isFirstrun={global.document.location.href === "about:welcome"}
-    isPrerendered={!!global.gActivityStreamPrerenderedState}
     locale={global.document.documentElement.lang}
     strings={global.gActivityStreamStrings} />
 </Provider>, document.getElementById("root"));
--- a/browser/components/newtab/content-src/asrouter/asrouter-content.jsx
+++ b/browser/components/newtab/content-src/asrouter/asrouter-content.jsx
@@ -1,12 +1,12 @@
 import {addLocaleData, IntlProvider} from "react-intl";
 import {actionCreators as ac} from "common/Actions.jsm";
 import {OUTGOING_MESSAGE_NAME as AS_GENERAL_OUTGOING_MESSAGE_NAME} from "content-src/lib/init-store";
-import {generateMessages} from "./rich-text-strings";
+import {generateBundles} from "./rich-text-strings";
 import {ImpressionsWrapper} from "./components/ImpressionsWrapper/ImpressionsWrapper";
 import {LocalizationProvider} from "fluent-react";
 import {NEWTAB_DARK_THEME} from "content-src/lib/constants";
 import {OnboardingMessage} from "./templates/OnboardingMessage/OnboardingMessage";
 import React from "react";
 import ReactDOM from "react-dom";
 import {ReturnToAMO} from "./templates/ReturnToAMO/ReturnToAMO";
 import {SnippetsTemplates} from "./templates/template-manifest";
@@ -252,17 +252,17 @@ export class ASRouterUISurface extends R
     return (
       <ImpressionsWrapper
         id="NEWTAB_FOOTER_BAR"
         message={this.state.message}
         sendImpression={this.sendImpression}
         shouldSendImpressionOnUpdate={shouldSendImpressionOnUpdate}
         // This helps with testing
         document={this.props.document}>
-          <LocalizationProvider messages={generateMessages(content)}>
+          <LocalizationProvider bundles={generateBundles(content)}>
             <SnippetComponent
               {...this.state.message}
               UISurface="NEWTAB_FOOTER_BAR"
               onBlock={this.onBlockById(this.state.message.id)}
               onDismiss={this.onDismissById(this.state.message.id)}
               onAction={ASRouterUtils.executeAction}
               sendClick={this.sendClick}
               sendUserActionTelemetry={this.sendUserActionTelemetry} />
@@ -293,17 +293,17 @@ export class ASRouterUISurface extends R
             onReady={this.triggerOnboarding}
             onBlock={this.onDismissById(message.id)}
             dispatch={this.props.dispatch} />
         </IntlProvider>
       );
     } else if (message.template === "return_to_amo_overlay") {
       global.document.body.classList.add("amo");
       return (
-        <LocalizationProvider messages={generateMessages({"amo_html": message.content.text})}>
+        <LocalizationProvider messages={generateBundles({"amo_html": message.content.text})}>
           <ReturnToAMO
             {...message}
             UISurface="NEWTAB_OVERLAY"
             onReady={this.triggerOnboarding}
             onBlock={this.onDismissById(message.id)}
             onAction={ASRouterUtils.executeAction}
             sendUserActionTelemetry={this.sendUserActionTelemetry} />
         </LocalizationProvider>
--- a/browser/components/newtab/content-src/asrouter/components/ModalOverlay/ModalOverlay.jsx
+++ b/browser/components/newtab/content-src/asrouter/components/ModalOverlay/ModalOverlay.jsx
@@ -19,19 +19,23 @@ export class ModalOverlayWrapper extends
 
   componentWillUnmount() {
     this.props.document.removeEventListener("keydown", this.onKeyDown);
     this.props.document.body.classList.remove("modal-open");
   }
 
   render() {
     const {props} = this;
+    let className = props.unstyled ? "" : "modalOverlayInner active";
+    if (props.innerClassName) {
+      className += ` ${props.innerClassName}`;
+    }
     return (<React.Fragment>
-      <div className="modalOverlayOuter active" onClick={props.onClose} role="presentation" />
-      <div className={`modalOverlayInner active ${props.innerClassName || ""}`}
+      <div className="modalOverlayOuter active" onClick={props.onClose} onKeyDown={this.onKeyDown} role="presentation" />
+      <div className={className}
         aria-labelledby={props.headerId}
         id={props.id}
         role="dialog">
         {props.children}
       </div>
     </React.Fragment>);
   }
 }
--- a/browser/components/newtab/content-src/asrouter/components/ModalOverlay/_ModalOverlay.scss
+++ b/browser/components/newtab/content-src/asrouter/components/ModalOverlay/_ModalOverlay.scss
@@ -4,31 +4,32 @@
   }
 }
 
 .modalOverlayOuter {
   background: var(--newtab-overlay-color);
   height: 100%;
   position: fixed;
   top: 0;
+  left: 0;
   width: 100%;
   display: none;
   z-index: 1100;
 
   &.active {
     display: block;
   }
 }
 
 .modalOverlayInner {
   width: 960px;
-  height: 570px;
   position: fixed;
-  top: calc(50% - 285px); // halfway down minus half the height of the modal
+  top: 20%;
   left: calc(50% - 480px); // halfway across minus half the width of the modal
+  max-height: calc(100% - 100px);
   background: $white;
   box-shadow: 0 1px 15px 0 $black-30;
   border-radius: 4px;
   display: none;
   z-index: 1101;
 
 
   // modal takes over entire screen
@@ -70,16 +71,17 @@
 
     @media(max-width: 850px) {
       margin-top: 30px;
     }
   }
 
   .footer {
     border-top: 1px solid $grey-30;
+    border-radius: 4px;
     height: 70px;
     width: 100%;
     position: absolute;
     bottom: 0;
     text-align: center;
     background-color: $white;
 
     // if modal is short enough, footer becomes sticky
--- a/browser/components/newtab/content-src/asrouter/rich-text-strings.js
+++ b/browser/components/newtab/content-src/asrouter/rich-text-strings.js
@@ -1,9 +1,9 @@
-import {MessageContext} from "fluent";
+import {FluentBundle} from "fluent";
 
 /**
  * Properties that allow rich text MUST be added to this list.
  *   key: the localization_id that should be used
  *   value: a property or array of properties on the message.content object
  */
 const RICH_TEXT_CONFIG = {
   "text": ["text", "scene1_text"],
@@ -16,25 +16,25 @@ const RICH_TEXT_CONFIG = {
 };
 
 export const RICH_TEXT_KEYS = Object.keys(RICH_TEXT_CONFIG);
 
 /**
  * Generates an array of messages suitable for fluent's localization provider
  * including all needed strings for rich text.
  * @param {object} content A .content object from an ASR message (i.e. message.content)
- * @returns {MessageContext[]} A array containing the fluent message context
+ * @returns {FluentBundle[]} A array containing the fluent message context
  */
-export function generateMessages(content) {
-  const cx = new MessageContext("en-US");
+export function generateBundles(content) {
+  const bundle = new FluentBundle("en-US");
 
   RICH_TEXT_KEYS.forEach(key => {
     const attrs = RICH_TEXT_CONFIG[key];
     const attrsToTry = Array.isArray(attrs) ? [...attrs] : [attrs];
     let string = "";
     while (!string && attrsToTry.length) {
       const attr = attrsToTry.pop();
       string = content[attr];
     }
-    cx.addMessages(`${key} = ${string}`);
+    bundle.addMessages(`${key} = ${string}`);
   });
-  return [cx];
+  return [bundle];
 }
--- a/browser/components/newtab/content-src/asrouter/templates/OnboardingMessage/OnboardingMessage.jsx
+++ b/browser/components/newtab/content-src/asrouter/templates/OnboardingMessage/OnboardingMessage.jsx
@@ -54,17 +54,17 @@ export class OnboardingMessage extends R
       link.rel = "localization";
     });
   }
 
   render() {
     const {props} = this;
     const {button_label, header} = props.extraTemplateStrings;
     return (
-      <ModalOverlay {...props} button_label={button_label} title={header}>
+      <ModalOverlay {...props} button_label={button_label} title={header} >
         <div className="onboardingMessageContainer">
           {props.bundle.map(message => (
             <OnboardingCard key={message.id}
               sendUserActionTelemetry={props.sendUserActionTelemetry}
               onAction={props.onAction}
               UISurface={props.UISurface}
               {...message} />
           ))}
--- a/browser/components/newtab/content-src/asrouter/templates/OnboardingMessage/_OnboardingMessage.scss
+++ b/browser/components/newtab/content-src/asrouter/templates/OnboardingMessage/_OnboardingMessage.scss
@@ -1,14 +1,15 @@
 .onboardingMessageContainer {
   display: grid;
   grid-column-gap: 21px;
   grid-template-columns: auto auto auto;
   padding-left: 30px;
   padding-right: 30px;
+  min-height: 500px;
 
   // at 850px, the cards go from vertical layout to horizontal layout
   @media(max-width: 850px) {
     grid-template-columns: none;
     grid-template-rows: auto auto auto;
     padding-left: 110px;
     padding-right: 110px;
   }
--- a/browser/components/newtab/content-src/components/ASRouterAdmin/ASRouterAdmin.jsx
+++ b/browser/components/newtab/content-src/components/ASRouterAdmin/ASRouterAdmin.jsx
@@ -534,17 +534,17 @@ export class ASRouterAdminInner extends 
   }
 
   renderPasteModal() {
     if (!this.state.pasteFromClipboard) {
       return null;
     }
     const errors = this.refs.targetingParamsEval && this.refs.targetingParamsEval.innerText.length;
     return (
-      <ModalOverlay title="New targeting parameters" button_label={errors ? "Cancel" : "Done"} onDoneButton={this.onPasteTargetingParams}>
+      <ModalOverlay innerStyle="pasteModal" title="New targeting parameters" button_label={errors ? "Cancel" : "Done"} onDismissBundle={this.onPasteTargetingParams}>
         <div className="onboardingMessage">
           <p>
             <textarea onChange={this.onNewTargetingParams} value={this.state.newStringTargetingParameters} rows="20" cols="60" />
           </p>
           <p ref="targetingParamsEval" />
         </div>
       </ModalOverlay>
     );
--- a/browser/components/newtab/content-src/components/ASRouterAdmin/ASRouterAdmin.scss
+++ b/browser/components/newtab/content-src/components/ASRouterAdmin/ASRouterAdmin.scss
@@ -214,9 +214,13 @@
     font-size: 16px;
     margin-bottom: 20px;
     border: 1px solid $border-color;
   }
 
   .ds-component {
     margin-bottom: 20px;
   }
+
+  .modalOverlayInner {
+    height: 80%;
+  }
 }
--- a/browser/components/newtab/content-src/components/Base/Base.jsx
+++ b/browser/components/newtab/content-src/components/Base/Base.jsx
@@ -1,17 +1,16 @@
 import {actionCreators as ac, actionTypes as at} from "common/Actions.jsm";
 import {addLocaleData, injectIntl, IntlProvider} from "react-intl";
 import {ASRouterAdmin} from "content-src/components/ASRouterAdmin/ASRouterAdmin";
 import {ASRouterUISurface} from "../../asrouter/asrouter-content";
 import {ConfirmDialog} from "content-src/components/ConfirmDialog/ConfirmDialog";
 import {connect} from "react-redux";
 import {DiscoveryStreamBase} from "content-src/components/DiscoveryStreamBase/DiscoveryStreamBase";
 import {ErrorBoundary} from "content-src/components/ErrorBoundary/ErrorBoundary";
-import {PrerenderData} from "common/PrerenderData.jsm";
 import React from "react";
 import {Search} from "content-src/components/Search/Search";
 import {Sections} from "content-src/components/Sections/Sections";
 
 const PrefsButton = injectIntl(props => (
   <div className="prefs-button">
     <button className="icon icon-settings" onClick={props.onClick} title={props.intl.formatMessage({id: "settings_pane_button_label"})} />
   </div>
@@ -42,26 +41,16 @@ export class _Base extends React.PureCom
   componentWillMount() {
     const {locale} = this.props;
     addLocaleDataForReactIntl(locale);
     if (this.props.isFirstrun) {
       global.document.body.classList.add("welcome", "hide-main");
     }
   }
 
-  componentDidMount() {
-    // Request state AFTER the first render to ensure we don't cause the
-    // prerendered DOM to be unmounted. Otherwise, NEW_TAB_STATE_REQUEST is
-    // dispatched right after the store is ready.
-    if (this.props.isPrerendered) {
-      this.props.dispatch(ac.AlsoToMain({type: at.NEW_TAB_STATE_REQUEST}));
-      this.props.dispatch(ac.AlsoToMain({type: at.PAGE_PRERENDERED}));
-    }
-  }
-
   componentWillUnmount() {
     this.updateTheme();
   }
 
   componentWillUpdate() {
     this.updateTheme();
   }
 
@@ -75,20 +64,19 @@ export class _Base extends React.PureCom
       document.body.classList.contains("inline-onboarding") ? "inline-onboarding" : "",
     ].filter(v => v).join(" ");
     global.document.body.className = bodyClassName;
   }
 
   render() {
     const {props} = this;
     const {App, locale, strings} = props;
-    const {initialized} = App;
     const isDevtoolsEnabled = props.Prefs.values["asrouter.devtoolsEnabled"];
 
-    if (!props.isPrerendered && !initialized) {
+    if (!App.initialized) {
       return null;
     }
 
     return (<IntlProvider locale={locale} messages={strings}>
       <ErrorBoundary className="base-content-fallback">
         <React.Fragment>
           <BaseContent {...this.props} />
           {isDevtoolsEnabled ? <ASRouterAdmin /> : null}
@@ -129,32 +117,30 @@ export class BaseContent extends React.P
   }
 
   render() {
     const {props} = this;
     const {App} = props;
     const {initialized} = App;
     const prefs = props.Prefs.values;
 
-    const shouldBeFixedToTop = PrerenderData.arePrefsValid(name => prefs[name]);
     const isDiscoveryStream = props.DiscoveryStream.config && props.DiscoveryStream.config.enabled;
     let filteredSections = props.Sections;
 
     // Filter out highlights for DS
     if (isDiscoveryStream) {
       filteredSections = filteredSections.filter(section => section.id !== "highlights");
     }
     const noSectionsEnabled = !prefs["feeds.topsites"] && filteredSections.filter(section => section.enabled).length === 0;
     const searchHandoffEnabled = prefs["improvesearch.handoffToAwesomebar"];
 
     const outerClassName = [
       "outer-wrapper",
       isDiscoveryStream && "ds-outer-wrapper-search-alignment",
       isDiscoveryStream && "ds-outer-wrapper-breakpoint-override",
-      shouldBeFixedToTop && "fixed-to-top",
       prefs.showSearch && this.state.fixedSearch && !noSectionsEnabled && "fixed-search",
       prefs.showSearch && noSectionsEnabled && "only-search",
     ].filter(v => v).join(" ");
 
     return (
       <div>
         <div className={outerClassName}>
           <main>
--- a/browser/components/newtab/content-src/components/Base/_Base.scss
+++ b/browser/components/newtab/content-src/components/Base/_Base.scss
@@ -1,19 +1,15 @@
 .outer-wrapper {
   color: var(--newtab-text-primary-color);
   display: flex;
   flex-grow: 1;
   min-height: 100vh;
   padding: ($section-spacing + $section-vertical-padding) $base-gutter $base-gutter;
 
-  &.fixed-to-top {
-    display: block;
-  }
-
   &.only-search {
     display: block;
     padding-top: 134px;
   }
 
   a {
     color: var(--newtab-link-primary-color);
   }
--- a/browser/components/newtab/content-src/components/ContextMenu/ContextMenu.jsx
+++ b/browser/components/newtab/content-src/components/ContextMenu/ContextMenu.jsx
@@ -32,17 +32,19 @@ export class ContextMenu extends React.P
   onClick(event) {
     // Eat all clicks on the context menu so they don't bubble up to window.
     // This prevents the context menu from closing when clicking disabled items
     // or the separators.
     event.stopPropagation();
   }
 
   render() {
-    return (<span role="menu" className="context-menu" onClick={this.onClick} onKeyDown={this.onClick} tabIndex="0" >
+    // Disabling focus on the menu span allows the first tab to focus on the first menu item instead of the wrapper.
+    // eslint-disable-next-line jsx-a11y/interactive-supports-focus
+    return (<span role="menu" className="context-menu" onClick={this.onClick} onKeyDown={this.onClick} >
       <ul className="context-menu-list">
         {this.props.options.map((option, i) => (option.type === "separator" ?
           (<li key={i} className="separator" />) :
           (option.type !== "empty" && <ContextMenuItem key={i} option={option} hideContext={this.hideContext} tabIndex="0" />)
         ))}
       </ul>
     </span>);
   }
--- a/browser/components/newtab/content-src/components/DiscoveryStreamImpressionStats/_ImpressionStats.scss
+++ b/browser/components/newtab/content-src/components/DiscoveryStreamImpressionStats/_ImpressionStats.scss
@@ -1,6 +1,7 @@
 .impression-observer {
   position: absolute;
+  top: 0;
   width: 100%;
   height: 100%;
   pointer-events: none;
 }
--- a/browser/components/newtab/content-src/components/TopSites/TopSites.jsx
+++ b/browser/components/newtab/content-src/components/TopSites/TopSites.jsx
@@ -1,14 +1,15 @@
 import {actionCreators as ac, actionTypes as at} from "common/Actions.jsm";
 import {MIN_CORNER_FAVICON_SIZE, MIN_RICH_FAVICON_SIZE, TOP_SITES_SOURCE} from "./TopSitesConstants";
 import {CollapsibleSection} from "content-src/components/CollapsibleSection/CollapsibleSection";
 import {ComponentPerfTimer} from "content-src/components/ComponentPerfTimer/ComponentPerfTimer";
 import {connect} from "react-redux";
 import {injectIntl} from "react-intl";
+import {ModalOverlayWrapper} from "../../asrouter/components/ModalOverlay/ModalOverlay";
 import React from "react";
 import {SearchShortcutsForm} from "./SearchShortcutsForm";
 import {TOP_SITES_MAX_SITES_PER_ROW} from "common/Reducers.jsm";
 import {TopSiteForm} from "./TopSiteForm";
 import {TopSiteList} from "./TopSite";
 
 function topSiteIconType(link) {
   if (link.customScreenshotURL) {
@@ -134,36 +135,34 @@ export class _TopSites extends React.Pur
         isFixed={props.isFixed}
         isFirst={props.isFirst}
         isLast={props.isLast}
         dispatch={props.dispatch}>
         <TopSiteList TopSites={props.TopSites} TopSitesRows={props.TopSitesRows} dispatch={props.dispatch} intl={props.intl} topSiteIconType={topSiteIconType} />
         <div className="edit-topsites-wrapper">
           {editForm &&
             <div className="edit-topsites">
-              <div className="modal-overlay" onClick={this.onEditFormClose} role="presentation" />
-              <div className="modal">
+              <ModalOverlayWrapper unstyled={true} onClose={this.onEditFormClose} innerClassName="modal" >
                 <TopSiteForm
                   site={props.TopSites.rows[editForm.index]}
                   onClose={this.onEditFormClose}
                   dispatch={this.props.dispatch}
                   intl={this.props.intl}
                   {...editForm} />
-              </div>
+              </ModalOverlayWrapper>
             </div>
           }
           {showSearchShortcutsForm &&
             <div className="edit-search-shortcuts">
-              <div className="modal-overlay" onClick={this.onSearchShortcutsFormClose} role="presentation" />
-              <div className="modal">
+              <ModalOverlayWrapper unstyled={true} onClose={this.onSearchShortcutsFormClose} innerClassName="modal" >
                 <SearchShortcutsForm
                   TopSites={props.TopSites}
                   onClose={this.onSearchShortcutsFormClose}
                   dispatch={this.props.dispatch} />
-              </div>
+              </ModalOverlayWrapper>
             </div>
           }
         </div>
       </CollapsibleSection>
     </ComponentPerfTimer>);
   }
 }
 
--- a/browser/components/newtab/content-src/lib/init-store.js
+++ b/browser/components/newtab/content-src/lib/init-store.js
@@ -1,17 +1,17 @@
 /* eslint-env mozilla/frame-script */
 
 import {actionCreators as ac, actionTypes as at, actionUtils as au} from "common/Actions.jsm";
 import {applyMiddleware, combineReducers, createStore} from "redux";
 
 export const MERGE_STORE_ACTION = "NEW_TAB_INITIAL_STATE";
 export const OUTGOING_MESSAGE_NAME = "ActivityStream:ContentToMain";
 export const INCOMING_MESSAGE_NAME = "ActivityStream:MainToContent";
-export const EARLY_QUEUED_ACTIONS = [at.SAVE_SESSION_PERF_DATA, at.PAGE_PRERENDERED];
+export const EARLY_QUEUED_ACTIONS = [at.SAVE_SESSION_PERF_DATA];
 
 /**
  * A higher-order function which returns a reducer that, on MERGE_STORE action,
  * will return the action.data object merged into the previous state.
  *
  * For all other actions, it merely calls mainReducer.
  *
  * Because we want this to merge the entire state object, it's written as a
@@ -109,20 +109,19 @@ export const queueEarlyMessageMiddleware
 
 /**
  * initStore - Create a store and listen for incoming actions
  *
  * @param  {object} reducers An object containing Redux reducers
  * @param  {object} intialState (optional) The initial state of the store, if desired
  * @return {object}          A redux store
  */
-export function initStore(reducers, initialState) {
+export function initStore(reducers) {
   const store = createStore(
     mergeStateReducer(combineReducers(reducers)),
-    initialState,
     global.RPMAddMessageListener && applyMiddleware(rehydrationMiddleware, queueEarlyMessageMiddleware, messageMiddleware)
   );
 
   store._didRehydrate = false;
   store._didRequestInitialState = false;
 
   if (global.RPMAddMessageListener) {
     global.RPMAddMessageListener(INCOMING_MESSAGE_NAME, msg => {
--- a/browser/components/newtab/css/activity-stream-linux.css
+++ b/browser/components/newtab/css/activity-stream-linux.css
@@ -358,18 +358,16 @@ input[type='text'], input[type='search']
     text-decoration: underline; }
 
 .outer-wrapper {
   color: var(--newtab-text-primary-color);
   display: flex;
   flex-grow: 1;
   min-height: 100vh;
   padding: 30px 32px 32px; }
-  .outer-wrapper.fixed-to-top {
-    display: block; }
   .outer-wrapper.only-search {
     display: block;
     padding-top: 134px; }
   .outer-wrapper a {
     color: var(--newtab-link-primary-color); }
 
 main {
   margin: auto;
@@ -1782,16 +1780,18 @@ main {
       text-decoration: underline; }
   .asrouter-admin .dsEnabled {
     padding: 10px;
     font-size: 16px;
     margin-bottom: 20px;
     border: 1px solid var(--newtab-border-secondary-color); }
   .asrouter-admin .ds-component {
     margin-bottom: 20px; }
+  .asrouter-admin .modalOverlayInner {
+    height: 80%; }
 
 .pocket-logged-in-cta {
   font-size: 13px;
   margin-inline-end: 20px;
   display: flex;
   align-items: flex-start; }
   .pocket-logged-in-cta .pocket-cta-button {
     white-space: nowrap;
@@ -2731,16 +2731,17 @@ main {
     .ds-message .title .link {
       line-height: 20px;
       font-size: 13px; }
       .ds-message .title .link:hover, .ds-message .title .link:focus {
         text-decoration: underline; }
 
 .impression-observer {
   position: absolute;
+  top: 0;
   width: 100%;
   height: 100%;
   pointer-events: none; }
 
 .section-empty-state {
   border: 1px solid var(--newtab-border-secondary-color);
   border-radius: 4px;
   display: flex;
@@ -2890,28 +2891,29 @@ body[lwt-newtab-brighttext] .scene2Icon 
 .activity-stream.modal-open {
   overflow: hidden; }
 
 .modalOverlayOuter {
   background: var(--newtab-overlay-color);
   height: 100%;
   position: fixed;
   top: 0;
+  left: 0;
   width: 100%;
   display: none;
   z-index: 1100; }
   .modalOverlayOuter.active {
     display: block; }
 
 .modalOverlayInner {
   width: 960px;
-  height: 570px;
   position: fixed;
-  top: calc(50% - 285px);
+  top: 20%;
   left: calc(50% - 480px);
+  max-height: calc(100% - 100px);
   background: #FFF;
   box-shadow: 0 1px 15px 0 rgba(0, 0, 0, 0.3);
   border-radius: 4px;
   display: none;
   z-index: 1101; }
   @media (max-width: 960px) {
     .modalOverlayInner {
       width: 100%;
@@ -2939,16 +2941,17 @@ body[lwt-newtab-brighttext] .scene2Icon 
     @media (max-width: 960px) {
       .modalOverlayInner h2 {
         margin-top: 100px; } }
     @media (max-width: 850px) {
       .modalOverlayInner h2 {
         margin-top: 30px; } }
   .modalOverlayInner .footer {
     border-top: 1px solid #D7D7DB;
+    border-radius: 4px;
     height: 70px;
     width: 100%;
     position: absolute;
     bottom: 0;
     text-align: center;
     background-color: #FFF; }
     @media (max-width: 850px) and (max-height: 730px) {
       .modalOverlayInner .footer {
@@ -3313,17 +3316,18 @@ body[lwt-newtab-brighttext] .scene2Icon 
   .submissionStatus .submitStatusTitle {
     font-size: 20px; }
 
 .onboardingMessageContainer {
   display: grid;
   grid-column-gap: 21px;
   grid-template-columns: auto auto auto;
   padding-left: 30px;
-  padding-right: 30px; }
+  padding-right: 30px;
+  min-height: 500px; }
   @media (max-width: 850px) {
     .onboardingMessageContainer {
       grid-template-columns: none;
       grid-template-rows: auto auto auto;
       padding-left: 110px;
       padding-right: 110px; } }
 
 .onboardingMessage {
--- a/browser/components/newtab/css/activity-stream-mac.css
+++ b/browser/components/newtab/css/activity-stream-mac.css
@@ -361,18 +361,16 @@ input[type='text'], input[type='search']
     text-decoration: underline; }
 
 .outer-wrapper {
   color: var(--newtab-text-primary-color);
   display: flex;
   flex-grow: 1;
   min-height: 100vh;
   padding: 30px 32px 32px; }
-  .outer-wrapper.fixed-to-top {
-    display: block; }
   .outer-wrapper.only-search {
     display: block;
     padding-top: 134px; }
   .outer-wrapper a {
     color: var(--newtab-link-primary-color); }
 
 main {
   margin: auto;
@@ -1785,16 +1783,18 @@ main {
       text-decoration: underline; }
   .asrouter-admin .dsEnabled {
     padding: 10px;
     font-size: 16px;
     margin-bottom: 20px;
     border: 1px solid var(--newtab-border-secondary-color); }
   .asrouter-admin .ds-component {
     margin-bottom: 20px; }
+  .asrouter-admin .modalOverlayInner {
+    height: 80%; }
 
 .pocket-logged-in-cta {
   font-size: 13px;
   margin-inline-end: 20px;
   display: flex;
   align-items: flex-start; }
   .pocket-logged-in-cta .pocket-cta-button {
     white-space: nowrap;
@@ -2734,16 +2734,17 @@ main {
     .ds-message .title .link {
       line-height: 20px;
       font-size: 13px; }
       .ds-message .title .link:hover, .ds-message .title .link:focus {
         text-decoration: underline; }
 
 .impression-observer {
   position: absolute;
+  top: 0;
   width: 100%;
   height: 100%;
   pointer-events: none; }
 
 .section-empty-state {
   border: 1px solid var(--newtab-border-secondary-color);
   border-radius: 4px;
   display: flex;
@@ -2893,28 +2894,29 @@ body[lwt-newtab-brighttext] .scene2Icon 
 .activity-stream.modal-open {
   overflow: hidden; }
 
 .modalOverlayOuter {
   background: var(--newtab-overlay-color);
   height: 100%;
   position: fixed;
   top: 0;
+  left: 0;
   width: 100%;
   display: none;
   z-index: 1100; }
   .modalOverlayOuter.active {
     display: block; }
 
 .modalOverlayInner {
   width: 960px;
-  height: 570px;
   position: fixed;
-  top: calc(50% - 285px);
+  top: 20%;
   left: calc(50% - 480px);
+  max-height: calc(100% - 100px);
   background: #FFF;
   box-shadow: 0 1px 15px 0 rgba(0, 0, 0, 0.3);
   border-radius: 4px;
   display: none;
   z-index: 1101; }
   @media (max-width: 960px) {
     .modalOverlayInner {
       width: 100%;
@@ -2942,16 +2944,17 @@ body[lwt-newtab-brighttext] .scene2Icon 
     @media (max-width: 960px) {
       .modalOverlayInner h2 {
         margin-top: 100px; } }
     @media (max-width: 850px) {
       .modalOverlayInner h2 {
         margin-top: 30px; } }
   .modalOverlayInner .footer {
     border-top: 1px solid #D7D7DB;
+    border-radius: 4px;
     height: 70px;
     width: 100%;
     position: absolute;
     bottom: 0;
     text-align: center;
     background-color: #FFF; }
     @media (max-width: 850px) and (max-height: 730px) {
       .modalOverlayInner .footer {
@@ -3316,17 +3319,18 @@ body[lwt-newtab-brighttext] .scene2Icon 
   .submissionStatus .submitStatusTitle {
     font-size: 20px; }
 
 .onboardingMessageContainer {
   display: grid;
   grid-column-gap: 21px;
   grid-template-columns: auto auto auto;
   padding-left: 30px;
-  padding-right: 30px; }
+  padding-right: 30px;
+  min-height: 500px; }
   @media (max-width: 850px) {
     .onboardingMessageContainer {
       grid-template-columns: none;
       grid-template-rows: auto auto auto;
       padding-left: 110px;
       padding-right: 110px; } }
 
 .onboardingMessage {
--- a/browser/components/newtab/css/activity-stream-windows.css
+++ b/browser/components/newtab/css/activity-stream-windows.css
@@ -358,18 +358,16 @@ input[type='text'], input[type='search']
     text-decoration: underline; }
 
 .outer-wrapper {
   color: var(--newtab-text-primary-color);
   display: flex;
   flex-grow: 1;
   min-height: 100vh;
   padding: 30px 32px 32px; }
-  .outer-wrapper.fixed-to-top {
-    display: block; }
   .outer-wrapper.only-search {
     display: block;
     padding-top: 134px; }
   .outer-wrapper a {
     color: var(--newtab-link-primary-color); }
 
 main {
   margin: auto;
@@ -1782,16 +1780,18 @@ main {
       text-decoration: underline; }
   .asrouter-admin .dsEnabled {
     padding: 10px;
     font-size: 16px;
     margin-bottom: 20px;
     border: 1px solid var(--newtab-border-secondary-color); }
   .asrouter-admin .ds-component {
     margin-bottom: 20px; }
+  .asrouter-admin .modalOverlayInner {
+    height: 80%; }
 
 .pocket-logged-in-cta {
   font-size: 13px;
   margin-inline-end: 20px;
   display: flex;
   align-items: flex-start; }
   .pocket-logged-in-cta .pocket-cta-button {
     white-space: nowrap;
@@ -2731,16 +2731,17 @@ main {
     .ds-message .title .link {
       line-height: 20px;
       font-size: 13px; }
       .ds-message .title .link:hover, .ds-message .title .link:focus {
         text-decoration: underline; }
 
 .impression-observer {
   position: absolute;
+  top: 0;
   width: 100%;
   height: 100%;
   pointer-events: none; }
 
 .section-empty-state {
   border: 1px solid var(--newtab-border-secondary-color);
   border-radius: 4px;
   display: flex;
@@ -2890,28 +2891,29 @@ body[lwt-newtab-brighttext] .scene2Icon 
 .activity-stream.modal-open {
   overflow: hidden; }
 
 .modalOverlayOuter {
   background: var(--newtab-overlay-color);
   height: 100%;
   position: fixed;
   top: 0;
+  left: 0;
   width: 100%;
   display: none;
   z-index: 1100; }
   .modalOverlayOuter.active {
     display: block; }
 
 .modalOverlayInner {
   width: 960px;
-  height: 570px;
   position: fixed;
-  top: calc(50% - 285px);
+  top: 20%;
   left: calc(50% - 480px);
+  max-height: calc(100% - 100px);
   background: #FFF;
   box-shadow: 0 1px 15px 0 rgba(0, 0, 0, 0.3);
   border-radius: 4px;
   display: none;
   z-index: 1101; }
   @media (max-width: 960px) {
     .modalOverlayInner {
       width: 100%;
@@ -2939,16 +2941,17 @@ body[lwt-newtab-brighttext] .scene2Icon 
     @media (max-width: 960px) {
       .modalOverlayInner h2 {
         margin-top: 100px; } }
     @media (max-width: 850px) {
       .modalOverlayInner h2 {
         margin-top: 30px; } }
   .modalOverlayInner .footer {
     border-top: 1px solid #D7D7DB;
+    border-radius: 4px;
     height: 70px;
     width: 100%;
     position: absolute;
     bottom: 0;
     text-align: center;
     background-color: #FFF; }
     @media (max-width: 850px) and (max-height: 730px) {
       .modalOverlayInner .footer {
@@ -3313,17 +3316,18 @@ body[lwt-newtab-brighttext] .scene2Icon 
   .submissionStatus .submitStatusTitle {
     font-size: 20px; }
 
 .onboardingMessageContainer {
   display: grid;
   grid-column-gap: 21px;
   grid-template-columns: auto auto auto;
   padding-left: 30px;
-  padding-right: 30px; }
+  padding-right: 30px;
+  min-height: 500px; }
   @media (max-width: 850px) {
     .onboardingMessageContainer {
       grid-template-columns: none;
       grid-template-rows: auto auto auto;
       padding-left: 110px;
       padding-right: 110px; } }
 
 .onboardingMessage {
--- a/browser/components/newtab/data/content/activity-stream.bundle.js
+++ b/browser/components/newtab/data/content/activity-stream.bundle.js
@@ -87,49 +87,42 @@
 /******/ ([
 /* 0 */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* WEBPACK VAR INJECTION */(function(global) {/* harmony import */ var common_Actions_jsm__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(2);
 /* harmony import */ var content_src_components_Base_Base__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(3);
-/* harmony import */ var content_src_lib_detect_user_session_start__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(52);
+/* harmony import */ var content_src_lib_detect_user_session_start__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(50);
 /* harmony import */ var content_src_lib_init_store__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(7);
-/* harmony import */ var react_redux__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(26);
+/* harmony import */ var react_redux__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(25);
 /* harmony import */ var react_redux__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(react_redux__WEBPACK_IMPORTED_MODULE_4__);
-/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(11);
+/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(10);
 /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_5___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_5__);
-/* harmony import */ var react_dom__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(16);
+/* harmony import */ var react_dom__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(15);
 /* harmony import */ var react_dom__WEBPACK_IMPORTED_MODULE_6___default = /*#__PURE__*/__webpack_require__.n(react_dom__WEBPACK_IMPORTED_MODULE_6__);
-/* harmony import */ var common_Reducers_jsm__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(57);
-
-
-
-
-
-
-
-
-const store = Object(content_src_lib_init_store__WEBPACK_IMPORTED_MODULE_3__["initStore"])(common_Reducers_jsm__WEBPACK_IMPORTED_MODULE_7__["reducers"], global.gActivityStreamPrerenderedState);
-new content_src_lib_detect_user_session_start__WEBPACK_IMPORTED_MODULE_2__["DetectUserSessionStart"](store).sendEventOrAddListener(); // If we are starting in a prerendered state, we must wait until the first render
-// to request state rehydration (see Base.jsx). If we are NOT in a prerendered state,
-// we can request it immedately.
-
-if (!global.gActivityStreamPrerenderedState) {
-  store.dispatch(common_Actions_jsm__WEBPACK_IMPORTED_MODULE_0__["actionCreators"].AlsoToMain({
-    type: common_Actions_jsm__WEBPACK_IMPORTED_MODULE_0__["actionTypes"].NEW_TAB_STATE_REQUEST
-  }));
-}
-
+/* harmony import */ var common_Reducers_jsm__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(55);
+
+
+
+
+
+
+
+
+const store = Object(content_src_lib_init_store__WEBPACK_IMPORTED_MODULE_3__["initStore"])(common_Reducers_jsm__WEBPACK_IMPORTED_MODULE_7__["reducers"]);
+new content_src_lib_detect_user_session_start__WEBPACK_IMPORTED_MODULE_2__["DetectUserSessionStart"](store).sendEventOrAddListener();
+store.dispatch(common_Actions_jsm__WEBPACK_IMPORTED_MODULE_0__["actionCreators"].AlsoToMain({
+  type: common_Actions_jsm__WEBPACK_IMPORTED_MODULE_0__["actionTypes"].NEW_TAB_STATE_REQUEST
+}));
 react_dom__WEBPACK_IMPORTED_MODULE_6___default.a.hydrate(react__WEBPACK_IMPORTED_MODULE_5___default.a.createElement(react_redux__WEBPACK_IMPORTED_MODULE_4__["Provider"], {
   store: store
 }, react__WEBPACK_IMPORTED_MODULE_5___default.a.createElement(content_src_components_Base_Base__WEBPACK_IMPORTED_MODULE_1__["Base"], {
   isFirstrun: global.document.location.href === "about:welcome",
-  isPrerendered: !!global.gActivityStreamPrerenderedState,
   locale: global.document.documentElement.lang,
   strings: global.gActivityStreamStrings
 })), document.getElementById("root"));
 /* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(1)))
 
 /***/ }),
 /* 1 */
 /***/ (function(module, exports) {
@@ -192,17 +185,17 @@ const globalImportContext = typeof Windo
 
 // Create an object that avoids accidental differing key/value pairs:
 // {
 //   INIT: "INIT",
 //   UNINIT: "UNINIT"
 // }
 const actionTypes = {};
 
-for (const type of ["ADDONS_INFO_REQUEST", "ADDONS_INFO_RESPONSE", "ARCHIVE_FROM_POCKET", "AS_ROUTER_INITIALIZED", "AS_ROUTER_PREF_CHANGED", "AS_ROUTER_TARGETING_UPDATE", "AS_ROUTER_TELEMETRY_USER_EVENT", "BLOCK_URL", "BOOKMARK_URL", "COPY_DOWNLOAD_LINK", "DELETE_BOOKMARK_BY_ID", "DELETE_FROM_POCKET", "DELETE_HISTORY_URL", "DIALOG_CANCEL", "DIALOG_OPEN", "DISCOVERY_STREAM_CONFIG_CHANGE", "DISCOVERY_STREAM_CONFIG_SETUP", "DISCOVERY_STREAM_CONFIG_SET_VALUE", "DISCOVERY_STREAM_FEEDS_UPDATE", "DISCOVERY_STREAM_FEED_UPDATE", "DISCOVERY_STREAM_IMPRESSION_STATS", "DISCOVERY_STREAM_LAYOUT_RESET", "DISCOVERY_STREAM_LAYOUT_UPDATE", "DISCOVERY_STREAM_LINK_BLOCKED", "DISCOVERY_STREAM_LOADED_CONTENT", "DISCOVERY_STREAM_SPOCS_CAPS", "DISCOVERY_STREAM_SPOCS_ENDPOINT", "DISCOVERY_STREAM_SPOCS_FILL", "DISCOVERY_STREAM_SPOCS_UPDATE", "DISCOVERY_STREAM_SPOC_IMPRESSION", "DOWNLOAD_CHANGED", "FAKE_FOCUS_SEARCH", "FILL_SEARCH_TERM", "HANDOFF_SEARCH_TO_AWESOMEBAR", "HIDE_SEARCH", "INIT", "NEW_TAB_INIT", "NEW_TAB_INITIAL_STATE", "NEW_TAB_LOAD", "NEW_TAB_REHYDRATED", "NEW_TAB_STATE_REQUEST", "NEW_TAB_UNLOAD", "OPEN_DOWNLOAD_FILE", "OPEN_LINK", "OPEN_NEW_WINDOW", "OPEN_PRIVATE_WINDOW", "OPEN_WEBEXT_SETTINGS", "PAGE_PRERENDERED", "PLACES_BOOKMARK_ADDED", "PLACES_BOOKMARK_REMOVED", "PLACES_HISTORY_CLEARED", "PLACES_LINKS_CHANGED", "PLACES_LINK_BLOCKED", "PLACES_LINK_DELETED", "PLACES_SAVED_TO_POCKET", "POCKET_CTA", "POCKET_LINK_DELETED_OR_ARCHIVED", "POCKET_LOGGED_IN", "POCKET_WAITING_FOR_SPOC", "PREFS_INITIAL_VALUES", "PREF_CHANGED", "PREVIEW_REQUEST", "PREVIEW_REQUEST_CANCEL", "PREVIEW_RESPONSE", "REMOVE_DOWNLOAD_FILE", "RICH_ICON_MISSING", "SAVE_SESSION_PERF_DATA", "SAVE_TO_POCKET", "SCREENSHOT_UPDATED", "SECTION_DEREGISTER", "SECTION_DISABLE", "SECTION_ENABLE", "SECTION_MOVE", "SECTION_OPTIONS_CHANGED", "SECTION_REGISTER", "SECTION_UPDATE", "SECTION_UPDATE_CARD", "SETTINGS_CLOSE", "SETTINGS_OPEN", "SET_PREF", "SHOW_DOWNLOAD_FILE", "SHOW_FIREFOX_ACCOUNTS", "SHOW_SEARCH", "SKIPPED_SIGNIN", "SNIPPETS_BLOCKLIST_CLEARED", "SNIPPETS_BLOCKLIST_UPDATED", "SNIPPETS_DATA", "SNIPPETS_PREVIEW_MODE", "SNIPPETS_RESET", "SNIPPET_BLOCKED", "SUBMIT_EMAIL", "SYSTEM_TICK", "TELEMETRY_IMPRESSION_STATS", "TELEMETRY_PERFORMANCE_EVENT", "TELEMETRY_UNDESIRED_EVENT", "TELEMETRY_USER_EVENT", "TOP_SITES_CANCEL_EDIT", "TOP_SITES_CLOSE_SEARCH_SHORTCUTS_MODAL", "TOP_SITES_EDIT", "TOP_SITES_INSERT", "TOP_SITES_OPEN_SEARCH_SHORTCUTS_MODAL", "TOP_SITES_PIN", "TOP_SITES_PREFS_UPDATED", "TOP_SITES_UNPIN", "TOP_SITES_UPDATED", "TOTAL_BOOKMARKS_REQUEST", "TOTAL_BOOKMARKS_RESPONSE", "TRAILHEAD_ENROLL_EVENT", "UNINIT", "UPDATE_PINNED_SEARCH_SHORTCUTS", "UPDATE_SEARCH_SHORTCUTS", "UPDATE_SECTION_PREFS", "WEBEXT_CLICK", "WEBEXT_DISMISS"]) {
+for (const type of ["ADDONS_INFO_REQUEST", "ADDONS_INFO_RESPONSE", "ARCHIVE_FROM_POCKET", "AS_ROUTER_INITIALIZED", "AS_ROUTER_PREF_CHANGED", "AS_ROUTER_TARGETING_UPDATE", "AS_ROUTER_TELEMETRY_USER_EVENT", "BLOCK_URL", "BOOKMARK_URL", "COPY_DOWNLOAD_LINK", "DELETE_BOOKMARK_BY_ID", "DELETE_FROM_POCKET", "DELETE_HISTORY_URL", "DIALOG_CANCEL", "DIALOG_OPEN", "DISCOVERY_STREAM_CONFIG_CHANGE", "DISCOVERY_STREAM_CONFIG_SETUP", "DISCOVERY_STREAM_CONFIG_SET_VALUE", "DISCOVERY_STREAM_FEEDS_UPDATE", "DISCOVERY_STREAM_FEED_UPDATE", "DISCOVERY_STREAM_IMPRESSION_STATS", "DISCOVERY_STREAM_LAYOUT_RESET", "DISCOVERY_STREAM_LAYOUT_UPDATE", "DISCOVERY_STREAM_LINK_BLOCKED", "DISCOVERY_STREAM_LOADED_CONTENT", "DISCOVERY_STREAM_SPOCS_CAPS", "DISCOVERY_STREAM_SPOCS_ENDPOINT", "DISCOVERY_STREAM_SPOCS_FILL", "DISCOVERY_STREAM_SPOCS_UPDATE", "DISCOVERY_STREAM_SPOC_IMPRESSION", "DOWNLOAD_CHANGED", "FAKE_FOCUS_SEARCH", "FILL_SEARCH_TERM", "HANDOFF_SEARCH_TO_AWESOMEBAR", "HIDE_SEARCH", "INIT", "NEW_TAB_INIT", "NEW_TAB_INITIAL_STATE", "NEW_TAB_LOAD", "NEW_TAB_REHYDRATED", "NEW_TAB_STATE_REQUEST", "NEW_TAB_UNLOAD", "OPEN_DOWNLOAD_FILE", "OPEN_LINK", "OPEN_NEW_WINDOW", "OPEN_PRIVATE_WINDOW", "OPEN_WEBEXT_SETTINGS", "PLACES_BOOKMARK_ADDED", "PLACES_BOOKMARK_REMOVED", "PLACES_HISTORY_CLEARED", "PLACES_LINKS_CHANGED", "PLACES_LINK_BLOCKED", "PLACES_LINK_DELETED", "PLACES_SAVED_TO_POCKET", "POCKET_CTA", "POCKET_LINK_DELETED_OR_ARCHIVED", "POCKET_LOGGED_IN", "POCKET_WAITING_FOR_SPOC", "PREFS_INITIAL_VALUES", "PREF_CHANGED", "PREVIEW_REQUEST", "PREVIEW_REQUEST_CANCEL", "PREVIEW_RESPONSE", "REMOVE_DOWNLOAD_FILE", "RICH_ICON_MISSING", "SAVE_SESSION_PERF_DATA", "SAVE_TO_POCKET", "SCREENSHOT_UPDATED", "SECTION_DEREGISTER", "SECTION_DISABLE", "SECTION_ENABLE", "SECTION_MOVE", "SECTION_OPTIONS_CHANGED", "SECTION_REGISTER", "SECTION_UPDATE", "SECTION_UPDATE_CARD", "SETTINGS_CLOSE", "SETTINGS_OPEN", "SET_PREF", "SHOW_DOWNLOAD_FILE", "SHOW_FIREFOX_ACCOUNTS", "SHOW_SEARCH", "SKIPPED_SIGNIN", "SNIPPETS_BLOCKLIST_CLEARED", "SNIPPETS_BLOCKLIST_UPDATED", "SNIPPETS_DATA", "SNIPPETS_PREVIEW_MODE", "SNIPPETS_RESET", "SNIPPET_BLOCKED", "SUBMIT_EMAIL", "SYSTEM_TICK", "TELEMETRY_IMPRESSION_STATS", "TELEMETRY_PERFORMANCE_EVENT", "TELEMETRY_UNDESIRED_EVENT", "TELEMETRY_USER_EVENT", "TOP_SITES_CANCEL_EDIT", "TOP_SITES_CLOSE_SEARCH_SHORTCUTS_MODAL", "TOP_SITES_EDIT", "TOP_SITES_INSERT", "TOP_SITES_OPEN_SEARCH_SHORTCUTS_MODAL", "TOP_SITES_PIN", "TOP_SITES_PREFS_UPDATED", "TOP_SITES_UNPIN", "TOP_SITES_UPDATED", "TOTAL_BOOKMARKS_REQUEST", "TOTAL_BOOKMARKS_RESPONSE", "TRAILHEAD_ENROLL_EVENT", "UNINIT", "UPDATE_PINNED_SEARCH_SHORTCUTS", "UPDATE_SEARCH_SHORTCUTS", "UPDATE_SECTION_PREFS", "WEBEXT_CLICK", "WEBEXT_DISMISS"]) {
   actionTypes[type] = type;
 } // These are acceptable actions for AS Router messages to have. They can show up
 // as call-to-action buttons in snippets, onboarding tour, etc.
 
 
 const ASRouterActions = {};
 
 for (const type of ["INSTALL_ADDON_FROM_URL", "OPEN_APPLICATIONS_MENU", "OPEN_PRIVATE_BROWSER_WINDOW", "OPEN_URL", "OPEN_ABOUT_PAGE", "OPEN_PREFERENCES_PAGE", "SHOW_FIREFOX_ACCOUNTS", "PIN_CURRENT_TAB"]) {
@@ -562,43 +555,41 @@ var actionUtils = {
 /* WEBPACK VAR INJECTION */(function(global) {/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "_Base", function() { return _Base; });
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "BaseContent", function() { return BaseContent; });
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Base", function() { return Base; });
 /* harmony import */ var common_Actions_jsm__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(2);
 /* harmony import */ var react_intl__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(4);
 /* harmony import */ var react_intl__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(react_intl__WEBPACK_IMPORTED_MODULE_1__);
 /* harmony import */ var content_src_components_ASRouterAdmin_ASRouterAdmin__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(5);
 /* harmony import */ var _asrouter_asrouter_content__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(6);
-/* harmony import */ var content_src_components_ConfirmDialog_ConfirmDialog__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(29);
-/* harmony import */ var react_redux__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(26);
+/* harmony import */ var content_src_components_ConfirmDialog_ConfirmDialog__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(28);
+/* harmony import */ var react_redux__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(25);
 /* harmony import */ var react_redux__WEBPACK_IMPORTED_MODULE_5___default = /*#__PURE__*/__webpack_require__.n(react_redux__WEBPACK_IMPORTED_MODULE_5__);
-/* harmony import */ var content_src_components_DiscoveryStreamBase_DiscoveryStreamBase__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(53);
-/* harmony import */ var content_src_components_ErrorBoundary_ErrorBoundary__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(35);
-/* harmony import */ var common_PrerenderData_jsm__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(46);
-/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(11);
-/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_9___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_9__);
-/* harmony import */ var content_src_components_Search_Search__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(47);
-/* harmony import */ var content_src_components_Sections_Sections__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(48);
+/* harmony import */ var content_src_components_DiscoveryStreamBase_DiscoveryStreamBase__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(51);
+/* harmony import */ var content_src_components_ErrorBoundary_ErrorBoundary__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(34);
+/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(10);
+/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_8___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_8__);
+/* harmony import */ var content_src_components_Search_Search__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(45);
+/* harmony import */ var content_src_components_Sections_Sections__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(46);
 function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
 
 
 
 
 
 
 
 
 
 
 
 
-
-const PrefsButton = Object(react_intl__WEBPACK_IMPORTED_MODULE_1__["injectIntl"])(props => react__WEBPACK_IMPORTED_MODULE_9___default.a.createElement("div", {
+const PrefsButton = Object(react_intl__WEBPACK_IMPORTED_MODULE_1__["injectIntl"])(props => react__WEBPACK_IMPORTED_MODULE_8___default.a.createElement("div", {
   className: "prefs-button"
-}, react__WEBPACK_IMPORTED_MODULE_9___default.a.createElement("button", {
+}, react__WEBPACK_IMPORTED_MODULE_8___default.a.createElement("button", {
   className: "icon icon-settings",
   onClick: props.onClick,
   title: props.intl.formatMessage({
     id: "settings_pane_button_label"
   })
 }))); // Add the locale data for pluralization and relative-time formatting for now,
 // this just uses english locale data. We can make this more sophisticated if
 // more features are needed.
@@ -623,42 +614,28 @@ function debounce(func, wait) {
       timer = null;
     };
 
     timer = setTimeout(wakeUp, wait);
     func.apply(this, args);
   };
 }
 
-class _Base extends react__WEBPACK_IMPORTED_MODULE_9___default.a.PureComponent {
+class _Base extends react__WEBPACK_IMPORTED_MODULE_8___default.a.PureComponent {
   componentWillMount() {
     const {
       locale
     } = this.props;
     addLocaleDataForReactIntl(locale);
 
     if (this.props.isFirstrun) {
       global.document.body.classList.add("welcome", "hide-main");
     }
   }
 
-  componentDidMount() {
-    // Request state AFTER the first render to ensure we don't cause the
-    // prerendered DOM to be unmounted. Otherwise, NEW_TAB_STATE_REQUEST is
-    // dispatched right after the store is ready.
-    if (this.props.isPrerendered) {
-      this.props.dispatch(common_Actions_jsm__WEBPACK_IMPORTED_MODULE_0__["actionCreators"].AlsoToMain({
-        type: common_Actions_jsm__WEBPACK_IMPORTED_MODULE_0__["actionTypes"].NEW_TAB_STATE_REQUEST
-      }));
-      this.props.dispatch(common_Actions_jsm__WEBPACK_IMPORTED_MODULE_0__["actionCreators"].AlsoToMain({
-        type: common_Actions_jsm__WEBPACK_IMPORTED_MODULE_0__["actionTypes"].PAGE_PRERENDERED
-      }));
-    }
-  }
-
   componentWillUnmount() {
     this.updateTheme();
   }
 
   componentWillUpdate() {
     this.updateTheme();
   }
 
@@ -673,35 +650,32 @@ class _Base extends react__WEBPACK_IMPOR
     const {
       props
     } = this;
     const {
       App,
       locale,
       strings
     } = props;
-    const {
-      initialized
-    } = App;
     const isDevtoolsEnabled = props.Prefs.values["asrouter.devtoolsEnabled"];
 
-    if (!props.isPrerendered && !initialized) {
+    if (!App.initialized) {
       return null;
     }
 
-    return react__WEBPACK_IMPORTED_MODULE_9___default.a.createElement(react_intl__WEBPACK_IMPORTED_MODULE_1__["IntlProvider"], {
+    return react__WEBPACK_IMPORTED_MODULE_8___default.a.createElement(react_intl__WEBPACK_IMPORTED_MODULE_1__["IntlProvider"], {
       locale: locale,
       messages: strings
-    }, react__WEBPACK_IMPORTED_MODULE_9___default.a.createElement(content_src_components_ErrorBoundary_ErrorBoundary__WEBPACK_IMPORTED_MODULE_7__["ErrorBoundary"], {
+    }, react__WEBPACK_IMPORTED_MODULE_8___default.a.createElement(content_src_components_ErrorBoundary_ErrorBoundary__WEBPACK_IMPORTED_MODULE_7__["ErrorBoundary"], {
       className: "base-content-fallback"
-    }, react__WEBPACK_IMPORTED_MODULE_9___default.a.createElement(react__WEBPACK_IMPORTED_MODULE_9___default.a.Fragment, null, react__WEBPACK_IMPORTED_MODULE_9___default.a.createElement(BaseContent, this.props), isDevtoolsEnabled ? react__WEBPACK_IMPORTED_MODULE_9___default.a.createElement(content_src_components_ASRouterAdmin_ASRouterAdmin__WEBPACK_IMPORTED_MODULE_2__["ASRouterAdmin"], null) : null)));
-  }
-
-}
-class BaseContent extends react__WEBPACK_IMPORTED_MODULE_9___default.a.PureComponent {
+    }, react__WEBPACK_IMPORTED_MODULE_8___default.a.createElement(react__WEBPACK_IMPORTED_MODULE_8___default.a.Fragment, null, react__WEBPACK_IMPORTED_MODULE_8___default.a.createElement(BaseContent, this.props), isDevtoolsEnabled ? react__WEBPACK_IMPORTED_MODULE_8___default.a.createElement(content_src_components_ASRouterAdmin_ASRouterAdmin__WEBPACK_IMPORTED_MODULE_2__["ASRouterAdmin"], null) : null)));
+  }
+
+}
+class BaseContent extends react__WEBPACK_IMPORTED_MODULE_8___default.a.PureComponent {
   constructor(props) {
     super(props);
     this.openPreferences = this.openPreferences.bind(this);
     this.onWindowScroll = debounce(this.onWindowScroll.bind(this), 5);
     this.state = {
       fixedSearch: false
     };
   }
@@ -743,44 +717,43 @@ class BaseContent extends react__WEBPACK
     } = this;
     const {
       App
     } = props;
     const {
       initialized
     } = App;
     const prefs = props.Prefs.values;
-    const shouldBeFixedToTop = common_PrerenderData_jsm__WEBPACK_IMPORTED_MODULE_8__["PrerenderData"].arePrefsValid(name => prefs[name]);
     const isDiscoveryStream = props.DiscoveryStream.config && props.DiscoveryStream.config.enabled;
     let filteredSections = props.Sections; // Filter out highlights for DS
 
     if (isDiscoveryStream) {
       filteredSections = filteredSections.filter(section => section.id !== "highlights");
     }
 
     const noSectionsEnabled = !prefs["feeds.topsites"] && filteredSections.filter(section => section.enabled).length === 0;
     const searchHandoffEnabled = prefs["improvesearch.handoffToAwesomebar"];
-    const outerClassName = ["outer-wrapper", isDiscoveryStream && "ds-outer-wrapper-search-alignment", isDiscoveryStream && "ds-outer-wrapper-breakpoint-override", shouldBeFixedToTop && "fixed-to-top", prefs.showSearch && this.state.fixedSearch && !noSectionsEnabled && "fixed-search", prefs.showSearch && noSectionsEnabled && "only-search"].filter(v => v).join(" ");
-    return react__WEBPACK_IMPORTED_MODULE_9___default.a.createElement("div", null, react__WEBPACK_IMPORTED_MODULE_9___default.a.createElement("div", {
+    const outerClassName = ["outer-wrapper", isDiscoveryStream && "ds-outer-wrapper-search-alignment", isDiscoveryStream && "ds-outer-wrapper-breakpoint-override", prefs.showSearch && this.state.fixedSearch && !noSectionsEnabled && "fixed-search", prefs.showSearch && noSectionsEnabled && "only-search"].filter(v => v).join(" ");
+    return react__WEBPACK_IMPORTED_MODULE_8___default.a.createElement("div", null, react__WEBPACK_IMPORTED_MODULE_8___default.a.createElement("div", {
       className: outerClassName
-    }, react__WEBPACK_IMPORTED_MODULE_9___default.a.createElement("main", null, prefs.showSearch && react__WEBPACK_IMPORTED_MODULE_9___default.a.createElement("div", {
+    }, react__WEBPACK_IMPORTED_MODULE_8___default.a.createElement("main", null, prefs.showSearch && react__WEBPACK_IMPORTED_MODULE_8___default.a.createElement("div", {
       className: "non-collapsible-section"
-    }, react__WEBPACK_IMPORTED_MODULE_9___default.a.createElement(content_src_components_ErrorBoundary_ErrorBoundary__WEBPACK_IMPORTED_MODULE_7__["ErrorBoundary"], null, react__WEBPACK_IMPORTED_MODULE_9___default.a.createElement(content_src_components_Search_Search__WEBPACK_IMPORTED_MODULE_10__["Search"], _extends({
+    }, react__WEBPACK_IMPORTED_MODULE_8___default.a.createElement(content_src_components_ErrorBoundary_ErrorBoundary__WEBPACK_IMPORTED_MODULE_7__["ErrorBoundary"], null, react__WEBPACK_IMPORTED_MODULE_8___default.a.createElement(content_src_components_Search_Search__WEBPACK_IMPORTED_MODULE_9__["Search"], _extends({
       showLogo: noSectionsEnabled,
       handoffEnabled: searchHandoffEnabled
-    }, props.Search)))), react__WEBPACK_IMPORTED_MODULE_9___default.a.createElement(_asrouter_asrouter_content__WEBPACK_IMPORTED_MODULE_3__["ASRouterUISurface"], {
+    }, props.Search)))), react__WEBPACK_IMPORTED_MODULE_8___default.a.createElement(_asrouter_asrouter_content__WEBPACK_IMPORTED_MODULE_3__["ASRouterUISurface"], {
       fxaEndpoint: this.props.Prefs.values.fxa_endpoint,
       dispatch: this.props.dispatch
-    }), react__WEBPACK_IMPORTED_MODULE_9___default.a.createElement("div", {
+    }), react__WEBPACK_IMPORTED_MODULE_8___default.a.createElement("div", {
       className: `body-wrapper${initialized ? " on" : ""}`
-    }, isDiscoveryStream ? react__WEBPACK_IMPORTED_MODULE_9___default.a.createElement(content_src_components_ErrorBoundary_ErrorBoundary__WEBPACK_IMPORTED_MODULE_7__["ErrorBoundary"], {
+    }, isDiscoveryStream ? react__WEBPACK_IMPORTED_MODULE_8___default.a.createElement(content_src_components_ErrorBoundary_ErrorBoundary__WEBPACK_IMPORTED_MODULE_7__["ErrorBoundary"], {
       className: "borderless-error"
-    }, react__WEBPACK_IMPORTED_MODULE_9___default.a.createElement(content_src_components_DiscoveryStreamBase_DiscoveryStreamBase__WEBPACK_IMPORTED_MODULE_6__["DiscoveryStreamBase"], null)) : react__WEBPACK_IMPORTED_MODULE_9___default.a.createElement(content_src_components_Sections_Sections__WEBPACK_IMPORTED_MODULE_11__["Sections"], null), react__WEBPACK_IMPORTED_MODULE_9___default.a.createElement(PrefsButton, {
+    }, react__WEBPACK_IMPORTED_MODULE_8___default.a.createElement(content_src_components_DiscoveryStreamBase_DiscoveryStreamBase__WEBPACK_IMPORTED_MODULE_6__["DiscoveryStreamBase"], null)) : react__WEBPACK_IMPORTED_MODULE_8___default.a.createElement(content_src_components_Sections_Sections__WEBPACK_IMPORTED_MODULE_10__["Sections"], null), react__WEBPACK_IMPORTED_MODULE_8___default.a.createElement(PrefsButton, {
       onClick: this.openPreferences
-    })), react__WEBPACK_IMPORTED_MODULE_9___default.a.createElement(content_src_components_ConfirmDialog_ConfirmDialog__WEBPACK_IMPORTED_MODULE_4__["ConfirmDialog"], null))));
+    })), react__WEBPACK_IMPORTED_MODULE_8___default.a.createElement(content_src_components_ConfirmDialog_ConfirmDialog__WEBPACK_IMPORTED_MODULE_4__["ConfirmDialog"], null))));
   }
 
 }
 const Base = Object(react_redux__WEBPACK_IMPORTED_MODULE_5__["connect"])(state => ({
   App: state.App,
   Prefs: state.Prefs,
   Sections: state.Sections,
   DiscoveryStream: state.DiscoveryStream,
@@ -802,22 +775,22 @@ module.exports = ReactIntl;
 __webpack_require__.r(__webpack_exports__);
 /* WEBPACK VAR INJECTION */(function(global) {/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ToggleStoryButton", function() { return ToggleStoryButton; });
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "DiscoveryStreamAdmin", function() { return DiscoveryStreamAdmin; });
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ASRouterAdminInner", function() { return ASRouterAdminInner; });
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "CollapseToggle", function() { return CollapseToggle; });
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ASRouterAdmin", function() { return ASRouterAdmin; });
 /* harmony import */ var common_Actions_jsm__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(2);
 /* harmony import */ var _asrouter_asrouter_content__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(6);
-/* harmony import */ var react_redux__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(26);
+/* harmony import */ var react_redux__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(25);
 /* harmony import */ var react_redux__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(react_redux__WEBPACK_IMPORTED_MODULE_2__);
-/* harmony import */ var _asrouter_components_ModalOverlay_ModalOverlay__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(15);
-/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(11);
+/* harmony import */ var _asrouter_components_ModalOverlay_ModalOverlay__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(14);
+/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(10);
 /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_4__);
-/* harmony import */ var _SimpleHashRouter__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(28);
+/* harmony import */ var _SimpleHashRouter__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(27);
 function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
 
 
 
 
 
 
 
@@ -1433,19 +1406,20 @@ class ASRouterAdminInner extends react__
 
   renderPasteModal() {
     if (!this.state.pasteFromClipboard) {
       return null;
     }
 
     const errors = this.refs.targetingParamsEval && this.refs.targetingParamsEval.innerText.length;
     return react__WEBPACK_IMPORTED_MODULE_4___default.a.createElement(_asrouter_components_ModalOverlay_ModalOverlay__WEBPACK_IMPORTED_MODULE_3__["ModalOverlay"], {
+      innerStyle: "pasteModal",
       title: "New targeting parameters",
       button_label: errors ? "Cancel" : "Done",
-      onDoneButton: this.onPasteTargetingParams
+      onDismissBundle: this.onPasteTargetingParams
     }, react__WEBPACK_IMPORTED_MODULE_4___default.a.createElement("div", {
       className: "onboardingMessage"
     }, react__WEBPACK_IMPORTED_MODULE_4___default.a.createElement("p", null, react__WEBPACK_IMPORTED_MODULE_4___default.a.createElement("textarea", {
       onChange: this.onNewTargetingParams,
       value: this.state.newStringTargetingParameters,
       rows: "20",
       cols: "60"
     })), react__WEBPACK_IMPORTED_MODULE_4___default.a.createElement("p", {
@@ -1763,29 +1737,29 @@ const ASRouterAdmin = Object(react_redux
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* WEBPACK VAR INJECTION */(function(global) {/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ASRouterUtils", function() { return ASRouterUtils; });
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ASRouterUISurface", function() { return ASRouterUISurface; });
 /* harmony import */ var react_intl__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(4);
 /* harmony import */ var react_intl__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react_intl__WEBPACK_IMPORTED_MODULE_0__);
 /* harmony import */ var common_Actions_jsm__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(2);
 /* harmony import */ var content_src_lib_init_store__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(7);
-/* harmony import */ var _rich_text_strings__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(9);
-/* harmony import */ var _components_ImpressionsWrapper_ImpressionsWrapper__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(10);
-/* harmony import */ var fluent_react__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(56);
-/* harmony import */ var content_src_lib_constants__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(13);
-/* harmony import */ var _templates_OnboardingMessage_OnboardingMessage__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(14);
-/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(11);
+/* harmony import */ var _rich_text_strings__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(54);
+/* harmony import */ var _components_ImpressionsWrapper_ImpressionsWrapper__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(9);
+/* harmony import */ var fluent_react__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(52);
+/* harmony import */ var content_src_lib_constants__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(12);
+/* harmony import */ var _templates_OnboardingMessage_OnboardingMessage__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(13);
+/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(10);
 /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_8___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_8__);
-/* harmony import */ var react_dom__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(16);
+/* harmony import */ var react_dom__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(15);
 /* harmony import */ var react_dom__WEBPACK_IMPORTED_MODULE_9___default = /*#__PURE__*/__webpack_require__.n(react_dom__WEBPACK_IMPORTED_MODULE_9__);
-/* harmony import */ var _templates_ReturnToAMO_ReturnToAMO__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(17);
-/* harmony import */ var _templates_template_manifest__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(54);
-/* harmony import */ var _templates_StartupOverlay_StartupOverlay__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(25);
-/* harmony import */ var _templates_Trailhead_Trailhead__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(27);
+/* harmony import */ var _templates_ReturnToAMO_ReturnToAMO__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(16);
+/* harmony import */ var _templates_template_manifest__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(53);
+/* harmony import */ var _templates_StartupOverlay_StartupOverlay__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(24);
+/* harmony import */ var _templates_Trailhead_Trailhead__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(26);
 function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
 
 
 
 
 
 
 
@@ -2148,17 +2122,17 @@ class ASRouterUISurface extends react__W
     return react__WEBPACK_IMPORTED_MODULE_8___default.a.createElement(_components_ImpressionsWrapper_ImpressionsWrapper__WEBPACK_IMPORTED_MODULE_4__["ImpressionsWrapper"], {
       id: "NEWTAB_FOOTER_BAR",
       message: this.state.message,
       sendImpression: this.sendImpression,
       shouldSendImpressionOnUpdate: shouldSendImpressionOnUpdate // This helps with testing
       ,
       document: this.props.document
     }, react__WEBPACK_IMPORTED_MODULE_8___default.a.createElement(fluent_react__WEBPACK_IMPORTED_MODULE_5__["LocalizationProvider"], {
-      messages: Object(_rich_text_strings__WEBPACK_IMPORTED_MODULE_3__["generateMessages"])(content)
+      bundles: Object(_rich_text_strings__WEBPACK_IMPORTED_MODULE_3__["generateBundles"])(content)
     }, react__WEBPACK_IMPORTED_MODULE_8___default.a.createElement(SnippetComponent, _extends({}, this.state.message, {
       UISurface: "NEWTAB_FOOTER_BAR",
       onBlock: this.onBlockById(this.state.message.id),
       onDismiss: this.onDismissById(this.state.message.id),
       onAction: ASRouterUtils.executeAction,
       sendClick: this.sendClick,
       sendUserActionTelemetry: this.sendUserActionTelemetry
     }))));
@@ -2190,17 +2164,17 @@ class ASRouterUISurface extends react__W
       }, react__WEBPACK_IMPORTED_MODULE_8___default.a.createElement(_templates_StartupOverlay_StartupOverlay__WEBPACK_IMPORTED_MODULE_12__["StartupOverlay"], {
         onReady: this.triggerOnboarding,
         onBlock: this.onDismissById(message.id),
         dispatch: this.props.dispatch
       }));
     } else if (message.template === "return_to_amo_overlay") {
       global.document.body.classList.add("amo");
       return react__WEBPACK_IMPORTED_MODULE_8___default.a.createElement(fluent_react__WEBPACK_IMPORTED_MODULE_5__["LocalizationProvider"], {
-        messages: Object(_rich_text_strings__WEBPACK_IMPORTED_MODULE_3__["generateMessages"])({
+        messages: Object(_rich_text_strings__WEBPACK_IMPORTED_MODULE_3__["generateBundles"])({
           "amo_html": message.content.text
         })
       }, react__WEBPACK_IMPORTED_MODULE_8___default.a.createElement(_templates_ReturnToAMO_ReturnToAMO__WEBPACK_IMPORTED_MODULE_10__["ReturnToAMO"], _extends({}, message, {
         UISurface: "NEWTAB_OVERLAY",
         onReady: this.triggerOnboarding,
         onBlock: this.onDismissById(message.id),
         onAction: ASRouterUtils.executeAction,
         sendUserActionTelemetry: this.sendUserActionTelemetry
@@ -2285,17 +2259,17 @@ ASRouterUISurface.defaultProps = {
 /* harmony import */ var redux__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(8);
 /* harmony import */ var redux__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(redux__WEBPACK_IMPORTED_MODULE_1__);
 /* eslint-env mozilla/frame-script */
 
 
 const MERGE_STORE_ACTION = "NEW_TAB_INITIAL_STATE";
 const OUTGOING_MESSAGE_NAME = "ActivityStream:ContentToMain";
 const INCOMING_MESSAGE_NAME = "ActivityStream:MainToContent";
-const EARLY_QUEUED_ACTIONS = [common_Actions_jsm__WEBPACK_IMPORTED_MODULE_0__["actionTypes"].SAVE_SESSION_PERF_DATA, common_Actions_jsm__WEBPACK_IMPORTED_MODULE_0__["actionTypes"].PAGE_PRERENDERED];
+const EARLY_QUEUED_ACTIONS = [common_Actions_jsm__WEBPACK_IMPORTED_MODULE_0__["actionTypes"].SAVE_SESSION_PERF_DATA];
 /**
  * A higher-order function which returns a reducer that, on MERGE_STORE action,
  * will return the action.data object merged into the previous state.
  *
  * For all other actions, it merely calls mainReducer.
  *
  * Because we want this to merge the entire state object, it's written as a
  * higher order function which takes the main reducer (itself often a call to
@@ -2402,18 +2376,18 @@ const queueEarlyMessageMiddleware = stor
 /**
  * initStore - Create a store and listen for incoming actions
  *
  * @param  {object} reducers An object containing Redux reducers
  * @param  {object} intialState (optional) The initial state of the store, if desired
  * @return {object}          A redux store
  */
 
-function initStore(reducers, initialState) {
-  const store = Object(redux__WEBPACK_IMPORTED_MODULE_1__["createStore"])(mergeStateReducer(Object(redux__WEBPACK_IMPORTED_MODULE_1__["combineReducers"])(reducers)), initialState, global.RPMAddMessageListener && Object(redux__WEBPACK_IMPORTED_MODULE_1__["applyMiddleware"])(rehydrationMiddleware, queueEarlyMessageMiddleware, messageMiddleware));
+function initStore(reducers) {
+  const store = Object(redux__WEBPACK_IMPORTED_MODULE_1__["createStore"])(mergeStateReducer(Object(redux__WEBPACK_IMPORTED_MODULE_1__["combineReducers"])(reducers)), global.RPMAddMessageListener && Object(redux__WEBPACK_IMPORTED_MODULE_1__["applyMiddleware"])(rehydrationMiddleware, queueEarlyMessageMiddleware, messageMiddleware));
   store._didRehydrate = false;
   store._didRequestInitialState = false;
 
   if (global.RPMAddMessageListener) {
     global.RPMAddMessageListener(INCOMING_MESSAGE_NAME, msg => {
       try {
         store.dispatch(msg.data);
       } catch (ex) {
@@ -2435,70 +2409,20 @@ function initStore(reducers, initialStat
 module.exports = Redux;
 
 /***/ }),
 /* 9 */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 
 "use strict";
 __webpack_require__.r(__webpack_exports__);
-/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "RICH_TEXT_KEYS", function() { return RICH_TEXT_KEYS; });
-/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "generateMessages", function() { return generateMessages; });
-/* harmony import */ var fluent__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(55);
-
-/**
- * Properties that allow rich text MUST be added to this list.
- *   key: the localization_id that should be used
- *   value: a property or array of properties on the message.content object
- */
-
-const RICH_TEXT_CONFIG = {
-  "text": ["text", "scene1_text"],
-  "success_text": "success_text",
-  "error_text": "error_text",
-  "scene2_text": "scene2_text",
-  "amo_html": "amo_html",
-  "privacy_html": "scene2_privacy_html",
-  "disclaimer_html": "scene2_disclaimer_html"
-};
-const RICH_TEXT_KEYS = Object.keys(RICH_TEXT_CONFIG);
-/**
- * Generates an array of messages suitable for fluent's localization provider
- * including all needed strings for rich text.
- * @param {object} content A .content object from an ASR message (i.e. message.content)
- * @returns {MessageContext[]} A array containing the fluent message context
- */
-
-function generateMessages(content) {
-  const cx = new fluent__WEBPACK_IMPORTED_MODULE_0__["MessageContext"]("en-US");
-  RICH_TEXT_KEYS.forEach(key => {
-    const attrs = RICH_TEXT_CONFIG[key];
-    const attrsToTry = Array.isArray(attrs) ? [...attrs] : [attrs];
-    let string = "";
-
-    while (!string && attrsToTry.length) {
-      const attr = attrsToTry.pop();
-      string = content[attr];
-    }
-
-    cx.addMessages(`${key} = ${string}`);
-  });
-  return [cx];
-}
-
-/***/ }),
-/* 10 */
-/***/ (function(module, __webpack_exports__, __webpack_require__) {
-
-"use strict";
-__webpack_require__.r(__webpack_exports__);
 /* WEBPACK VAR INJECTION */(function(global) {/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "VISIBLE", function() { return VISIBLE; });
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "VISIBILITY_CHANGE_EVENT", function() { return VISIBILITY_CHANGE_EVENT; });
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ImpressionsWrapper", function() { return ImpressionsWrapper; });
-/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(11);
+/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(10);
 /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);
 
 const VISIBLE = "visible";
 const VISIBILITY_CHANGE_EVENT = "visibilitychange";
 /**
  * Component wrapper used to send telemetry pings on every impression.
  */
 
@@ -2557,29 +2481,29 @@ class ImpressionsWrapper extends react__
 }
 ImpressionsWrapper.defaultProps = {
   document: global.document,
   sendOnMount: true
 };
 /* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(1)))
 
 /***/ }),
-/* 11 */
+/* 10 */
 /***/ (function(module, exports) {
 
 module.exports = React;
 
 /***/ }),
-/* 12 */
+/* 11 */
 /***/ (function(module, exports) {
 
 module.exports = PropTypes;
 
 /***/ }),
-/* 13 */
+/* 12 */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* WEBPACK VAR INJECTION */(function(global) {/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "IS_NEWTAB", function() { return IS_NEWTAB; });
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "NEWTAB_DARK_THEME", function() { return NEWTAB_DARK_THEME; });
 const IS_NEWTAB = global.document && global.document.documentURI === "about:newtab";
 const NEWTAB_DARK_THEME = {
@@ -2606,25 +2530,25 @@ const NEWTAB_DARK_THEME = {
     "g": 249,
     "b": 250,
     "a": 1
   }
 };
 /* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(1)))
 
 /***/ }),
-/* 14 */
+/* 13 */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "OnboardingCard", function() { return OnboardingCard; });
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "OnboardingMessage", function() { return OnboardingMessage; });
-/* harmony import */ var _components_ModalOverlay_ModalOverlay__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(15);
-/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(11);
+/* harmony import */ var _components_ModalOverlay_ModalOverlay__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(14);
+/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(10);
 /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_1__);
 function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
 
 
 
 const FLUENT_FILES = ["branding/brand.ftl", "browser/branding/sync-brand.ftl", "browser/newtab/onboarding.ftl"];
 class OnboardingCard extends react__WEBPACK_IMPORTED_MODULE_1___default.a.PureComponent {
   constructor(props) {
@@ -2700,24 +2624,24 @@ class OnboardingMessage extends react__W
       onAction: props.onAction,
       UISurface: props.UISurface
     }, message)))));
   }
 
 }
 
 /***/ }),
-/* 15 */
+/* 14 */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* WEBPACK VAR INJECTION */(function(global) {/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ModalOverlayWrapper", function() { return ModalOverlayWrapper; });
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ModalOverlay", function() { return ModalOverlay; });
-/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(11);
+/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(10);
 /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);
 
 class ModalOverlayWrapper extends react__WEBPACK_IMPORTED_MODULE_0___default.a.PureComponent {
   constructor(props) {
     super(props);
     this.onKeyDown = this.onKeyDown.bind(this);
   }
 
@@ -2736,22 +2660,29 @@ class ModalOverlayWrapper extends react_
     this.props.document.removeEventListener("keydown", this.onKeyDown);
     this.props.document.body.classList.remove("modal-open");
   }
 
   render() {
     const {
       props
     } = this;
+    let className = props.unstyled ? "" : "modalOverlayInner active";
+
+    if (props.innerClassName) {
+      className += ` ${props.innerClassName}`;
+    }
+
     return react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(react__WEBPACK_IMPORTED_MODULE_0___default.a.Fragment, null, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("div", {
       className: "modalOverlayOuter active",
       onClick: props.onClose,
+      onKeyDown: this.onKeyDown,
       role: "presentation"
     }), react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("div", {
-      className: `modalOverlayInner active ${props.innerClassName || ""}`,
+      className: className,
       "aria-labelledby": props.headerId,
       id: props.id,
       role: "dialog"
     }, props.children));
   }
 
 }
 ModalOverlayWrapper.defaultProps = {
@@ -2772,31 +2703,31 @@ class ModalOverlay extends react__WEBPAC
       onClick: this.props.onDismissBundle
     }, " ", button_label, " ")));
   }
 
 }
 /* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(1)))
 
 /***/ }),
-/* 16 */
+/* 15 */
 /***/ (function(module, exports) {
 
 module.exports = ReactDOM;
 
 /***/ }),
-/* 17 */
+/* 16 */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ReturnToAMO", function() { return ReturnToAMO; });
-/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(11);
+/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(10);
 /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);
-/* harmony import */ var _components_RichText_RichText__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(18);
+/* harmony import */ var _components_RichText_RichText__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(17);
 
  // Alt text if available; in the future this should come from the server. See bug 1551711
 
 const ICON_ALT_TEXT = "";
 class ReturnToAMO extends react__WEBPACK_IMPORTED_MODULE_0___default.a.PureComponent {
   constructor(props) {
     super(props);
     this.onClickAddExtension = this.onClickAddExtension.bind(this);
@@ -2867,28 +2798,28 @@ class ReturnToAMO extends react__WEBPACK
       onClick: this.onBlockButton,
       className: "default grey ReturnToAMOGetStarted"
     }, " ", content.secondary_button.label, " ")));
   }
 
 }
 
 /***/ }),
-/* 18 */
+/* 17 */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "convertLinks", function() { return convertLinks; });
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "RichText", function() { return RichText; });
-/* harmony import */ var fluent_react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(56);
-/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(11);
+/* harmony import */ var fluent_react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(52);
+/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(10);
 /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_1__);
-/* harmony import */ var _rich_text_strings__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(9);
-/* harmony import */ var _template_utils__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(19);
+/* harmony import */ var _rich_text_strings__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(54);
+/* harmony import */ var _template_utils__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(18);
 function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
 
 
 
 
  // Elements allowed in snippet content
 
 const ALLOWED_TAGS = {
@@ -2939,17 +2870,17 @@ function RichText(props) {
   }
 
   return react__WEBPACK_IMPORTED_MODULE_1___default.a.createElement(fluent_react__WEBPACK_IMPORTED_MODULE_0__["Localized"], _extends({
     id: props.localization_id
   }, ALLOWED_TAGS, props.customElements, convertLinks(props.links, props.sendClick, props.doNotAutoBlock, props.openNewWindow)), react__WEBPACK_IMPORTED_MODULE_1___default.a.createElement("span", null, props.text));
 }
 
 /***/ }),
-/* 19 */
+/* 18 */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "safeURI", function() { return safeURI; });
 function safeURI(url) {
   if (!url) {
     return "";
@@ -2963,59 +2894,59 @@ function safeURI(url) {
   if (!isAllowed) {
     console.warn(`The protocol ${protocol} is not allowed for template URLs.`); // eslint-disable-line no-console
   }
 
   return isAllowed ? url : "";
 }
 
 /***/ }),
-/* 20 */
+/* 19 */
 /***/ (function(module) {
 
 module.exports = {"title":"EOYSnippet","description":"Fundraising Snippet","version":"1.1.0","type":"object","definitions":{"plainText":{"description":"Plain text (no HTML allowed)","type":"string"},"richText":{"description":"Text with HTML subset allowed: i, b, u, strong, em, br","type":"string"},"link_url":{"description":"Target for links or buttons","type":"string","format":"uri"}},"properties":{"donation_form_url":{"type":"string","description":"Url to the donation form."},"currency_code":{"type":"string","description":"The code for the currency. Examle gbp, cad, usd.","default":"usd"},"locale":{"type":"string","description":"String for the locale code.","default":"en-US"},"text":{"allOf":[{"$ref":"#/definitions/richText"},{"description":"Main body text of snippet. HTML subset allowed: i, b, u, strong, em, br"}]},"text_color":{"type":"string","description":"Modify the text message color"},"background_color":{"type":"string","description":"Snippet background color."},"highlight_color":{"type":"string","description":"Paragraph em highlight color."},"donation_amount_first":{"type":"number","description":"First button amount."},"donation_amount_second":{"type":"number","description":"Second button amount."},"donation_amount_third":{"type":"number","description":"Third button amount."},"donation_amount_fourth":{"type":"number","description":"Fourth button amount."},"selected_button":{"type":"string","description":"Default donation_amount_second. Donation amount button that's selected by default.","default":"donation_amount_second"},"icon":{"type":"string","description":"Snippet icon. 64x64px. SVG or PNG preferred."},"icon_dark_theme":{"type":"string","description":"Snippet icon. Dark theme variant. 64x64px. SVG or PNG preferred."},"title":{"allOf":[{"$ref":"#/definitions/plainText"},{"description":"Snippet title displayed before snippet text"}]},"title_icon":{"type":"string","description":"Small icon that shows up before the title / text. 16x16px. SVG or PNG preferred. Grayscale."},"title_icon_dark_theme":{"type":"string","description":"Small icon that shows up before the title / text. Dark theme variant. 16x16px. SVG or PNG preferred. Grayscale."},"button_label":{"allOf":[{"$ref":"#/definitions/plainText"},{"description":"Text for a button next to main snippet text that links to button_url. Requires button_url."}]},"button_color":{"type":"string","description":"The text color of the button. Valid CSS color."},"button_background_color":{"type":"string","description":"The background color of the button. Valid CSS color."},"block_button_text":{"type":"string","description":"Tooltip text used for dismiss button."},"monthly_checkbox_label_text":{"type":"string","description":"Label text for monthly checkbox.","default":"Make my donation monthly"},"test":{"type":"string","description":"Different styles for the snippet. Options are bold and takeover."},"do_not_autoblock":{"type":"boolean","description":"Used to prevent blocking the snippet after the CTA (link or button) has been clicked"},"links":{"additionalProperties":{"url":{"allOf":[{"$ref":"#/definitions/link_url"},{"description":"The url where the link points to."}]},"metric":{"type":"string","description":"Custom event name sent with telemetry event."},"args":{"type":"string","description":"Additional parameters for link action, example which specific menu the button should open"}}}},"additionalProperties":false,"required":["text","donation_form_url","donation_amount_first","donation_amount_second","donation_amount_third","donation_amount_fourth","button_label","currency_code"],"dependencies":{"button_color":["button_label"],"button_background_color":["button_label"]}};
 
 /***/ }),
-/* 21 */
+/* 20 */
 /***/ (function(module) {
 
 module.exports = {"title":"SimpleSnippet","description":"A simple template with an icon, text, and optional button.","version":"1.1.1","type":"object","definitions":{"plainText":{"description":"Plain text (no HTML allowed)","type":"string"},"richText":{"description":"Text with HTML subset allowed: i, b, u, strong, em, br","type":"string"},"link_url":{"description":"Target for links or buttons","type":"string","format":"uri"}},"properties":{"title":{"allOf":[{"$ref":"#/definitions/plainText"},{"description":"Snippet title displayed before snippet text"}]},"text":{"allOf":[{"$ref":"#/definitions/richText"},{"description":"Main body text of snippet. HTML subset allowed: i, b, u, strong, em, br"}]},"icon":{"type":"string","description":"Snippet icon. 64x64px. SVG or PNG preferred."},"icon_dark_theme":{"type":"string","description":"Snippet icon, dark theme variant. 64x64px. SVG or PNG preferred."},"title_icon":{"type":"string","description":"Small icon that shows up before the title / text. 16x16px. SVG or PNG preferred. Grayscale."},"title_icon_dark_theme":{"type":"string","description":"Small icon that shows up before the title / text. Dark theme variant. 16x16px. SVG or PNG preferred. Grayscale."},"button_action":{"type":"string","description":"The type of action the button should trigger."},"button_url":{"allOf":[{"$ref":"#/definitions/link_url"},{"description":"A url, button_label links to this"}]},"button_action_args":{"type":"string","description":"Additional parameters for button action, example which specific menu the button should open"},"button_label":{"allOf":[{"$ref":"#/definitions/plainText"},{"description":"Text for a button next to main snippet text that links to button_url. Requires button_url."}]},"button_color":{"type":"string","description":"The text color of the button. Valid CSS color."},"button_background_color":{"type":"string","description":"The background color of the button. Valid CSS color."},"block_button_text":{"type":"string","description":"Tooltip text used for dismiss button.","default":"Remove this"},"tall":{"type":"boolean","description":"To be used by fundraising only, increases height to roughly 120px. Defaults to false."},"do_not_autoblock":{"type":"boolean","description":"Used to prevent blocking the snippet after the CTA (link or button) has been clicked"},"links":{"additionalProperties":{"url":{"allOf":[{"$ref":"#/definitions/link_url"},{"description":"The url where the link points to."}]},"metric":{"type":"string","description":"Custom event name sent with telemetry event."},"args":{"type":"string","description":"Additional parameters for link action, example which specific menu the button should open"}}},"section_title_icon":{"type":"string","description":"Section title icon. 16x16px. SVG or PNG preferred. section_title_text must also be specified to display."},"section_title_icon_dark_theme":{"type":"string","description":"Section title icon, dark theme variant. 16x16px. SVG or PNG preferred. section_title_text must also be specified to display."},"section_title_text":{"type":"string","description":"Section title text. section_title_icon must also be specified to display."},"section_title_url":{"allOf":[{"$ref":"#/definitions/link_url"},{"description":"A url, section_title_text links to this"}]}},"additionalProperties":false,"required":["text"],"dependencies":{"button_action":["button_label"],"button_url":["button_label"],"button_color":["button_label"],"button_background_color":["button_label"],"section_title_url":["section_title_text"]}};
 
 /***/ }),
-/* 22 */
+/* 21 */
 /***/ (function(module) {
 
 module.exports = {"title":"FXASignupSnippet","description":"A snippet template for FxA sign up/sign in","version":"1.1.0","type":"object","definitions":{"plainText":{"description":"Plain text (no HTML allowed)","type":"string"},"richText":{"description":"Text with HTML subset allowed: i, b, u, strong, em, br","type":"string"},"link_url":{"description":"Target for links or buttons","type":"string","format":"uri"}},"properties":{"scene1_title":{"allof":[{"$ref":"#/definitions/plainText"},{"description":"snippet title displayed before snippet text"}]},"scene1_text":{"allOf":[{"$ref":"#/definitions/richText"},{"description":"Main body text of snippet. HTML subset allowed: i, b, u, strong, em, br"}]},"scene2_title":{"allOf":[{"$ref":"#/definitions/plainText"},{"description":"Title displayed before text in scene 2. Should be plain text."}]},"scene2_text":{"allOf":[{"$ref":"#/definitions/richText"},{"description":"Main body text of snippet. HTML subset allowed: i, b, u, strong, em, br"}]},"scene1_icon":{"type":"string","description":"Snippet icon. 64x64px. SVG or PNG preferred."},"scene1_icon_dark_theme":{"type":"string","description":"Snippet icon. Dark theme variant. 64x64px. SVG or PNG preferred."},"scene1_title_icon":{"type":"string","description":"Small icon that shows up before the title / text. 16x16px. SVG or PNG preferred. Grayscale."},"scene1_title_icon_dark_theme":{"type":"string","description":"Small icon that shows up before the title / text. Dark theme variant. 16x16px. SVG or PNG preferred. Grayscale."},"scene2_email_placeholder_text":{"type":"string","description":"Value to show while input is empty.","default":"Your email here"},"scene2_button_label":{"type":"string","description":"Label for form submit button","default":"Sign me up"},"scene2_dismiss_button_text":{"type":"string","description":"Label for the dismiss button when the sign-up form is expanded.","default":"Dismiss"},"hidden_inputs":{"type":"object","description":"Each entry represents a hidden input, key is used as value for the name property.","properties":{"action":{"type":"string","enum":["email"]},"context":{"type":"string","enum":["fx_desktop_v3"]},"entrypoint":{"type":"string","enum":["snippets"]},"service":{"type":"string","enum":["sync"]},"utm_content":{"type":"number","description":"Firefox version number"},"utm_source":{"type":"string","enum":["snippet"]},"utm_campaign":{"type":"string","description":"(fxa) Value to pass through to GA as utm_campaign."},"utm_term":{"type":"string","description":"(fxa) Value to pass through to GA as utm_term."},"additionalProperties":false}},"scene1_button_label":{"allOf":[{"$ref":"#/definitions/plainText"},{"description":"Text for a button next to main snippet text that links to button_url. Requires button_url."}],"default":"Learn more"},"scene1_button_color":{"type":"string","description":"The text color of the button. Valid CSS color."},"scene1_button_background_color":{"type":"string","description":"The background color of the button. Valid CSS color."},"do_not_autoblock":{"type":"boolean","description":"Used to prevent blocking the snippet after the CTA (link or button) has been clicked","default":false},"utm_campaign":{"type":"string","description":"(fxa) Value to pass through to GA as utm_campaign."},"utm_term":{"type":"string","description":"(fxa) Value to pass through to GA as utm_term."},"links":{"additionalProperties":{"url":{"allOf":[{"$ref":"#/definitions/link_url"},{"description":"The url where the link points to."}]},"metric":{"type":"string","description":"Custom event name sent with telemetry event."}}}},"additionalProperties":false,"required":["scene1_text","scene2_text","scene1_button_label"],"dependencies":{"scene1_button_color":["scene1_button_label"],"scene1_button_background_color":["scene1_button_label"]}};
 
 /***/ }),
-/* 23 */
+/* 22 */
 /***/ (function(module) {
 
 module.exports = {"title":"NewsletterSnippet","description":"A snippet template for send to device mobile download","version":"1.1.0","type":"object","definitions":{"plainText":{"description":"Plain text (no HTML allowed)","type":"string"},"richText":{"description":"Text with HTML subset allowed: i, b, u, strong, em, br","type":"string"},"link_url":{"description":"Target for links or buttons","type":"string","format":"uri"}},"properties":{"locale":{"type":"string","description":"Two to five character string for the locale code","default":"en-US"},"scene1_title":{"allof":[{"$ref":"#/definitions/plainText"},{"description":"snippet title displayed before snippet text"}]},"scene1_text":{"allOf":[{"$ref":"#/definitions/richText"},{"description":"Main body text of snippet. HTML subset allowed: i, b, u, strong, em, br"}]},"scene2_title":{"allOf":[{"$ref":"#/definitions/plainText"},{"description":"Title displayed before text in scene 2. Should be plain text."}]},"scene2_text":{"allOf":[{"$ref":"#/definitions/richText"},{"description":"Main body text of snippet. HTML subset allowed: i, b, u, strong, em, br"}]},"scene1_icon":{"type":"string","description":"Snippet icon. 64x64px. SVG or PNG preferred."},"scene1_icon_dark_theme":{"type":"string","description":"Snippet icon. Dark theme variant. 64x64px. SVG or PNG preferred."},"scene1_title_icon":{"type":"string","description":"Small icon that shows up before the title / text. 16x16px. SVG or PNG preferred. Grayscale."},"scene1_title_icon_dark_theme":{"type":"string","description":"Small icon that shows up before the title / text. Dark theme variant. 16x16px. SVG or PNG preferred. Grayscale."},"scene2_email_placeholder_text":{"type":"string","description":"Value to show while input is empty.","default":"Your email here"},"scene2_button_label":{"type":"string","description":"Label for form submit button","default":"Sign me up"},"scene2_privacy_html":{"type":"string","description":"(send to device) Html for disclaimer and link underneath input box."},"scene2_dismiss_button_text":{"type":"string","description":"Label for the dismiss button when the sign-up form is expanded.","default":"Dismiss"},"hidden_inputs":{"type":"object","description":"Each entry represents a hidden input, key is used as value for the name property.","properties":{"fmt":{"type":"string","description":"","default":"H"}}},"scene1_button_label":{"allOf":[{"$ref":"#/definitions/plainText"},{"description":"Text for a button next to main snippet text that links to button_url. Requires button_url."}],"default":"Learn more"},"scene1_button_color":{"type":"string","description":"The text color of the button. Valid CSS color."},"scene1_button_background_color":{"type":"string","description":"The background color of the button. Valid CSS color."},"do_not_autoblock":{"type":"boolean","description":"Used to prevent blocking the snippet after the CTA (link or button) has been clicked","default":false},"success_text":{"type":"string","description":"Message shown on successful registration."},"error_text":{"type":"string","description":"Message shown if registration failed."},"scene2_newsletter":{"type":"string","description":"Newsletter/basket id user is subscribing to.","default":"mozilla-foundation"},"links":{"additionalProperties":{"url":{"allOf":[{"$ref":"#/definitions/link_url"},{"description":"The url where the link points to."}]},"metric":{"type":"string","description":"Custom event name sent with telemetry event."}}}},"additionalProperties":false,"required":["scene1_text","scene2_text","scene1_button_label"],"dependencies":{"scene1_button_color":["scene1_button_label"],"scene1_button_background_color":["scene1_button_label"]}};
 
 /***/ }),
-/* 24 */
+/* 23 */
 /***/ (function(module) {
 
 module.exports = {"title":"SendToDeviceSnippet","description":"A snippet template for send to device mobile download","version":"1.1.0","type":"object","definitions":{"plainText":{"description":"Plain text (no HTML allowed)","type":"string"},"richText":{"description":"Text with HTML subset allowed: i, b, u, strong, em, br","type":"string"},"link_url":{"description":"Target for links or buttons","type":"string","format":"uri"}},"properties":{"locale":{"type":"string","description":"Two to five character string for the locale code","default":"en-US"},"country":{"type":"string","description":"Two character string for the country code (used for SMS)","default":"us"},"scene1_title":{"allof":[{"$ref":"#/definitions/plainText"},{"description":"snippet title displayed before snippet text"}]},"scene1_text":{"allOf":[{"$ref":"#/definitions/richText"},{"description":"Main body text of snippet. HTML subset allowed: i, b, u, strong, em, br"}]},"scene2_title":{"allOf":[{"$ref":"#/definitions/plainText"},{"description":"Title displayed before text in scene 2. Should be plain text."}]},"scene2_text":{"allOf":[{"$ref":"#/definitions/richText"},{"description":"Main body text of snippet. HTML subset allowed: i, b, u, strong, em, br"}]},"scene1_icon":{"type":"string","description":"Snippet icon. 64x64px. SVG or PNG preferred."},"scene1_icon_dark_theme":{"type":"string","description":"Snippet icon. Dark theme variant. 64x64px. SVG or PNG preferred."},"scene2_icon":{"type":"string","description":"(send to device) Image to display above the form. Dark theme variant. 98x98px. SVG or PNG preferred."},"scene2_icon_dark_theme":{"type":"string","description":"(send to device) Image to display above the form. 98x98px. SVG or PNG preferred."},"scene1_title_icon":{"type":"string","description":"Small icon that shows up before the title / text. 16x16px. SVG or PNG preferred. Grayscale."},"scene1_title_icon_dark_theme":{"type":"string","description":"Small icon that shows up before the title / text. Dark theme variant. 16x16px. SVG or PNG preferred. Grayscale."},"scene2_button_label":{"type":"string","description":"Label for form submit button","default":"Send"},"scene2_input_placeholder":{"type":"string","description":"(send to device) Value to show while input is empty.","default":"Your email here"},"scene2_disclaimer_html":{"type":"string","description":"(send to device) Html for disclaimer and link underneath input box."},"scene2_dismiss_button_text":{"type":"string","description":"Label for the dismiss button when the sign-up form is expanded.","default":"Dismiss"},"hidden_inputs":{"type":"object","description":"Each entry represents a hidden input, key is used as value for the name property.","properties":{"action":{"type":"string","enum":["email"]},"context":{"type":"string","enum":["fx_desktop_v3"]},"entrypoint":{"type":"string","enum":["snippets"]},"service":{"type":"string","enum":["sync"]},"utm_content":{"type":"string","description":"Firefox version number"},"utm_source":{"type":"string","enum":["snippet"]},"utm_campaign":{"type":"string","description":"(fxa) Value to pass through to GA as utm_campaign."},"utm_term":{"type":"string","description":"(fxa) Value to pass through to GA as utm_term."},"additionalProperties":false}},"scene1_button_label":{"allOf":[{"$ref":"#/definitions/plainText"},{"description":"Text for a button next to main snippet text that links to button_url. Requires button_url."}],"default":"Learn more"},"scene1_button_color":{"type":"string","description":"The text color of the button. Valid CSS color."},"scene1_button_background_color":{"type":"string","description":"The background color of the button. Valid CSS color."},"do_not_autoblock":{"type":"boolean","description":"Used to prevent blocking the snippet after the CTA (link or button) has been clicked","default":false},"success_title":{"type":"string","description":"(send to device) Title shown before text on successful registration."},"success_text":{"type":"string","description":"Message shown on successful registration."},"error_text":{"type":"string","description":"Message shown if registration failed."},"include_sms":{"type":"boolean","description":"(send to device) Allow users to send an SMS message with the form?","default":false},"message_id_sms":{"type":"string","description":"(send to device) Newsletter/basket id representing the SMS message to be sent."},"message_id_email":{"type":"string","description":"(send to device) Newsletter/basket id representing the email message to be sent. Must be a value from the 'Slug' column here: https://basket.mozilla.org/news/."},"utm_campaign":{"type":"string","description":"(fxa) Value to pass through to GA as utm_campaign."},"utm_term":{"type":"string","description":"(fxa) Value to pass through to GA as utm_term."},"links":{"additionalProperties":{"url":{"allOf":[{"$ref":"#/definitions/link_url"},{"description":"The url where the link points to."}]},"metric":{"type":"string","description":"Custom event name sent with telemetry event."}}}},"additionalProperties":false,"required":["scene1_text","scene2_text","scene1_button_label"],"dependencies":{"scene1_button_color":["scene1_button_label"],"scene1_button_background_color":["scene1_button_label"]}};
 
 /***/ }),
-/* 25 */
+/* 24 */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "_StartupOverlay", function() { return _StartupOverlay; });
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "StartupOverlay", function() { return StartupOverlay; });
 /* harmony import */ var common_Actions_jsm__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(2);
 /* harmony import */ var react_intl__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(4);
 /* harmony import */ var react_intl__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(react_intl__WEBPACK_IMPORTED_MODULE_1__);
-/* harmony import */ var react_redux__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(26);
+/* harmony import */ var react_redux__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(25);
 /* harmony import */ var react_redux__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(react_redux__WEBPACK_IMPORTED_MODULE_2__);
-/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(11);
+/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(10);
 /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_3__);
 
 
 
 
 class _StartupOverlay extends react__WEBPACK_IMPORTED_MODULE_3___default.a.PureComponent {
   constructor(props) {
     super(props);
@@ -3300,35 +3231,35 @@ class _StartupOverlay extends react__WEB
 
 const getState = state => ({
   fxa_endpoint: state.Prefs.values.fxa_endpoint
 });
 
 const StartupOverlay = Object(react_redux__WEBPACK_IMPORTED_MODULE_2__["connect"])(getState)(Object(react_intl__WEBPACK_IMPORTED_MODULE_1__["injectIntl"])(_StartupOverlay));
 
 /***/ }),
-/* 26 */
+/* 25 */
 /***/ (function(module, exports) {
 
 module.exports = ReactRedux;
 
 /***/ }),
-/* 27 */
+/* 26 */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* WEBPACK VAR INJECTION */(function(global) {/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "_Trailhead", function() { return _Trailhead; });
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Trailhead", function() { return Trailhead; });
 /* harmony import */ var common_Actions_jsm__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(2);
 /* harmony import */ var react_intl__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(4);
 /* harmony import */ var react_intl__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(react_intl__WEBPACK_IMPORTED_MODULE_1__);
-/* harmony import */ var _components_ModalOverlay_ModalOverlay__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(15);
-/* harmony import */ var _OnboardingMessage_OnboardingMessage__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(14);
-/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(11);
+/* harmony import */ var _components_ModalOverlay_ModalOverlay__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(14);
+/* harmony import */ var _OnboardingMessage_OnboardingMessage__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(13);
+/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(10);
 /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_4__);
 function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
 
 
 
 
 
 
@@ -3748,23 +3679,23 @@ class _Trailhead extends react__WEBPACK_
     }))) : null);
   }
 
 }
 const Trailhead = Object(react_intl__WEBPACK_IMPORTED_MODULE_1__["injectIntl"])(_Trailhead);
 /* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(1)))
 
 /***/ }),
-/* 28 */
+/* 27 */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* WEBPACK VAR INJECTION */(function(global) {/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SimpleHashRouter", function() { return SimpleHashRouter; });
-/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(11);
+/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(10);
 /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);
 
 class SimpleHashRouter extends react__WEBPACK_IMPORTED_MODULE_0___default.a.PureComponent {
   constructor(props) {
     super(props);
     this.onHashChange = this.onHashChange.bind(this);
     this.state = {
       hash: global.location.hash
@@ -3794,29 +3725,29 @@ class SimpleHashRouter extends react__WE
       }
     });
   }
 
 }
 /* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(1)))
 
 /***/ }),
-/* 29 */
+/* 28 */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "_ConfirmDialog", function() { return _ConfirmDialog; });
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ConfirmDialog", function() { return ConfirmDialog; });
 /* harmony import */ var common_Actions_jsm__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(2);
-/* harmony import */ var react_redux__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(26);
+/* harmony import */ var react_redux__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(25);
 /* harmony import */ var react_redux__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(react_redux__WEBPACK_IMPORTED_MODULE_1__);
 /* harmony import */ var react_intl__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(4);
 /* harmony import */ var react_intl__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(react_intl__WEBPACK_IMPORTED_MODULE_2__);
-/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(11);
+/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(10);
 /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_3__);
 
 
 
 
 /**
  * ConfirmDialog component.
  * One primary action button, one cancel button.
@@ -3902,31 +3833,31 @@ class _ConfirmDialog extends react__WEBP
       id: this.props.data.confirm_button_string_id
     })))));
   }
 
 }
 const ConfirmDialog = Object(react_redux__WEBPACK_IMPORTED_MODULE_1__["connect"])(state => state.Dialog)(_ConfirmDialog);
 
 /***/ }),
-/* 30 */
+/* 29 */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "_LinkMenu", function() { return _LinkMenu; });
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "LinkMenu", function() { return LinkMenu; });
 /* harmony import */ var common_Actions_jsm__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(2);
-/* harmony import */ var react_redux__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(26);
+/* harmony import */ var react_redux__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(25);
 /* harmony import */ var react_redux__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(react_redux__WEBPACK_IMPORTED_MODULE_1__);
-/* harmony import */ var content_src_components_ContextMenu_ContextMenu__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(31);
+/* harmony import */ var content_src_components_ContextMenu_ContextMenu__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(30);
 /* harmony import */ var react_intl__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(4);
 /* harmony import */ var react_intl__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(react_intl__WEBPACK_IMPORTED_MODULE_3__);
-/* harmony import */ var content_src_lib_link_menu_options__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(32);
-/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(11);
+/* harmony import */ var content_src_lib_link_menu_options__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(31);
+/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(10);
 /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_5___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_5__);
 
 
 
 
 
 
 const DEFAULT_SITE_MENU_OPTIONS = ["CheckPinTopSite", "EditTopSite", "Separator", "OpenInNewWindow", "OpenInPrivateWindow", "Separator", "BlockUrl"];
@@ -4001,24 +3932,24 @@ class _LinkMenu extends react__WEBPACK_I
 const getState = state => ({
   isPrivateBrowsingEnabled: state.Prefs.values.isPrivateBrowsingEnabled,
   platform: state.Prefs.values.platform
 });
 
 const LinkMenu = Object(react_redux__WEBPACK_IMPORTED_MODULE_1__["connect"])(getState)(Object(react_intl__WEBPACK_IMPORTED_MODULE_3__["injectIntl"])(_LinkMenu));
 
 /***/ }),
-/* 31 */
+/* 30 */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* WEBPACK VAR INJECTION */(function(global) {/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ContextMenu", function() { return ContextMenu; });
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ContextMenuItem", function() { return ContextMenuItem; });
-/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(11);
+/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(10);
 /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);
 
 class ContextMenu extends react__WEBPACK_IMPORTED_MODULE_0___default.a.PureComponent {
   constructor(props) {
     super(props);
     this.hideContext = this.hideContext.bind(this);
     this.onShow = this.onShow.bind(this);
     this.onClick = this.onClick.bind(this);
@@ -4048,22 +3979,23 @@ class ContextMenu extends react__WEBPACK
   onClick(event) {
     // Eat all clicks on the context menu so they don't bubble up to window.
     // This prevents the context menu from closing when clicking disabled items
     // or the separators.
     event.stopPropagation();
   }
 
   render() {
+    // Disabling focus on the menu span allows the first tab to focus on the first menu item instead of the wrapper.
+    // eslint-disable-next-line jsx-a11y/interactive-supports-focus
     return react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("span", {
       role: "menu",
       className: "context-menu",
       onClick: this.onClick,
-      onKeyDown: this.onClick,
-      tabIndex: "0"
+      onKeyDown: this.onClick
     }, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("ul", {
       className: "context-menu-list"
     }, this.props.options.map((option, i) => option.type === "separator" ? react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("li", {
       key: i,
       className: "separator"
     }) : option.type !== "empty" && react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement(ContextMenuItem, {
       key: i,
       option: option,
@@ -4124,17 +4056,17 @@ class ContextMenuItem extends react__WEB
       className: `icon icon-spacer icon-${option.icon}`
     }), option.label));
   }
 
 }
 /* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(1)))
 
 /***/ }),
-/* 32 */
+/* 31 */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "GetPlatformString", function() { return GetPlatformString; });
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "LinkMenuOptions", function() { return LinkMenuOptions; });
 /* harmony import */ var common_Actions_jsm__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(2);
 
@@ -4417,25 +4349,25 @@ const LinkMenuOptions = {
   CheckBookmark: site => site.bookmarkGuid ? LinkMenuOptions.RemoveBookmark(site) : LinkMenuOptions.AddBookmark(site),
   CheckPinTopSite: (site, index) => site.isPinned ? LinkMenuOptions.UnpinTopSite(site) : LinkMenuOptions.PinTopSite(site, index),
   CheckSavedToPocket: (site, index) => site.pocket_id ? LinkMenuOptions.DeleteFromPocket(site) : LinkMenuOptions.SaveToPocket(site, index),
   CheckBookmarkOrArchive: site => site.pocket_id ? LinkMenuOptions.ArchiveFromPocket(site) : LinkMenuOptions.CheckBookmark(site),
   OpenInPrivateWindow: (site, index, eventSource, isEnabled) => isEnabled ? _OpenInPrivateWindow(site) : LinkMenuOptions.EmptyItem()
 };
 
 /***/ }),
-/* 33 */
+/* 32 */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* WEBPACK VAR INJECTION */(function(global) {/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "INTERSECTION_RATIO", function() { return INTERSECTION_RATIO; });
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ImpressionStats", function() { return ImpressionStats; });
 /* harmony import */ var common_Actions_jsm__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(2);
-/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(11);
+/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(10);
 /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_1__);
 
 
 const VISIBLE = "visible";
 const VISIBILITY_CHANGE_EVENT = "visibilitychange"; // Per analytical requirement, we set the minimal intersection ratio to
 // 0.5, and an impression is identified when the wrapped item has at least
 // 50% visibility.
 //
@@ -4638,31 +4570,31 @@ ImpressionStats.defaultProps = {
   IntersectionObserver: global.IntersectionObserver,
   document: global.document,
   rows: [],
   source: ""
 };
 /* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(1)))
 
 /***/ }),
-/* 34 */
+/* 33 */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* WEBPACK VAR INJECTION */(function(global) {/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "_CollapsibleSection", function() { return _CollapsibleSection; });
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "CollapsibleSection", function() { return CollapsibleSection; });
 /* harmony import */ var react_intl__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(4);
 /* harmony import */ var react_intl__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react_intl__WEBPACK_IMPORTED_MODULE_0__);
 /* harmony import */ var common_Actions_jsm__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(2);
-/* harmony import */ var content_src_components_ErrorBoundary_ErrorBoundary__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(35);
-/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(11);
+/* harmony import */ var content_src_components_ErrorBoundary_ErrorBoundary__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(34);
+/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(10);
 /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_3__);
-/* harmony import */ var content_src_components_SectionMenu_SectionMenu__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(37);
-/* harmony import */ var content_src_lib_section_menu_options__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(38);
+/* harmony import */ var content_src_components_SectionMenu_SectionMenu__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(36);
+/* harmony import */ var content_src_lib_section_menu_options__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(37);
 
 
 
 
 
 
 const VISIBLE = "visible";
 const VISIBILITY_CHANGE_EVENT = "visibilitychange";
@@ -4948,27 +4880,27 @@ class _CollapsibleSection extends react_
   Prefs: {
     values: {}
   }
 };
 const CollapsibleSection = Object(react_intl__WEBPACK_IMPORTED_MODULE_0__["injectIntl"])(_CollapsibleSection);
 /* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(1)))
 
 /***/ }),
-/* 35 */
+/* 34 */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ErrorBoundaryFallback", function() { return ErrorBoundaryFallback; });
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ErrorBoundary", function() { return ErrorBoundary; });
-/* harmony import */ var content_src_components_A11yLinkButton_A11yLinkButton__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(36);
+/* harmony import */ var content_src_components_A11yLinkButton_A11yLinkButton__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(35);
 /* harmony import */ var react_intl__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(4);
 /* harmony import */ var react_intl__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(react_intl__WEBPACK_IMPORTED_MODULE_1__);
-/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(11);
+/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(10);
 /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_2__);
 
 
 
 class ErrorBoundaryFallback extends react__WEBPACK_IMPORTED_MODULE_2___default.a.PureComponent {
   constructor(props) {
     super(props);
     this.windowObj = this.props.windowObj || window;
@@ -5038,23 +4970,23 @@ class ErrorBoundary extends react__WEBPA
   }
 
 }
 ErrorBoundary.defaultProps = {
   FallbackComponent: ErrorBoundaryFallback
 };
 
 /***/ }),
-/* 36 */
+/* 35 */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "A11yLinkButton", function() { return A11yLinkButton; });
-/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(11);
+/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(10);
 /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);
 function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
 
 
 function A11yLinkButton(props) {
   // function for merging classes, if necessary
   let className = "a11y-link-button";
 
@@ -5065,30 +4997,30 @@ function A11yLinkButton(props) {
   return react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("button", _extends({
     type: "button"
   }, props, {
     className: className
   }), props.children);
 }
 
 /***/ }),
-/* 37 */
+/* 36 */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "_SectionMenu", function() { return _SectionMenu; });
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SectionMenu", function() { return SectionMenu; });
 /* harmony import */ var common_Actions_jsm__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(2);
-/* harmony import */ var content_src_components_ContextMenu_ContextMenu__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(31);
+/* harmony import */ var content_src_components_ContextMenu_ContextMenu__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(30);
 /* harmony import */ var react_intl__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(4);
 /* harmony import */ var react_intl__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(react_intl__WEBPACK_IMPORTED_MODULE_2__);
-/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(11);
+/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(10);
 /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_3__);
-/* harmony import */ var content_src_lib_section_menu_options__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(38);
+/* harmony import */ var content_src_lib_section_menu_options__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(37);
 
 
 
 
 
 const DEFAULT_SECTION_MENU_OPTIONS = ["MoveUp", "MoveDown", "Separator", "RemoveSection", "CheckCollapsed", "Separator", "ManageSection"];
 const WEBEXT_SECTION_MENU_OPTIONS = ["MoveUp", "MoveDown", "Separator", "CheckCollapsed", "Separator", "ManageWebExtension"];
 class _SectionMenu extends react__WEBPACK_IMPORTED_MODULE_3___default.a.PureComponent {
@@ -5153,17 +5085,17 @@ class _SectionMenu extends react__WEBPAC
       options: this.getOptions()
     });
   }
 
 }
 const SectionMenu = Object(react_intl__WEBPACK_IMPORTED_MODULE_2__["injectIntl"])(_SectionMenu);
 
 /***/ }),
-/* 38 */
+/* 37 */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SectionMenuOptions", function() { return SectionMenuOptions; });
 /* harmony import */ var common_Actions_jsm__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(2);
 
 /**
@@ -5280,51 +5212,53 @@ const SectionMenuOptions = {
       }
     }),
     userEvent: "MENU_PRIVACY_NOTICE"
   }),
   CheckCollapsed: section => section.collapsed ? SectionMenuOptions.ExpandSection(section) : SectionMenuOptions.CollapseSection(section)
 };
 
 /***/ }),
-/* 39 */
+/* 38 */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* WEBPACK VAR INJECTION */(function(global) {/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "_TopSites", function() { return _TopSites; });
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "TopSites", function() { return TopSites; });
 /* harmony import */ var common_Actions_jsm__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(2);
-/* harmony import */ var _TopSitesConstants__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(40);
-/* harmony import */ var content_src_components_CollapsibleSection_CollapsibleSection__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(34);
-/* harmony import */ var content_src_components_ComponentPerfTimer_ComponentPerfTimer__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(41);
-/* harmony import */ var react_redux__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(26);
+/* harmony import */ var _TopSitesConstants__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(39);
+/* harmony import */ var content_src_components_CollapsibleSection_CollapsibleSection__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(33);
+/* harmony import */ var content_src_components_ComponentPerfTimer_ComponentPerfTimer__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(40);
+/* harmony import */ var react_redux__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(25);
 /* harmony import */ var react_redux__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(react_redux__WEBPACK_IMPORTED_MODULE_4__);
 /* harmony import */ var react_intl__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(4);
 /* harmony import */ var react_intl__WEBPACK_IMPORTED_MODULE_5___default = /*#__PURE__*/__webpack_require__.n(react_intl__WEBPACK_IMPORTED_MODULE_5__);
-/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(11);
-/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_6___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_6__);
-/* harmony import */ var _SearchShortcutsForm__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(43);
-/* harmony import */ var common_Reducers_jsm__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(57);
-/* harmony import */ var _TopSiteForm__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(59);
-/* harmony import */ var _TopSite__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(44);
+/* harmony import */ var _asrouter_components_ModalOverlay_ModalOverlay__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(14);
+/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(10);
+/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_7___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_7__);
+/* harmony import */ var _SearchShortcutsForm__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(42);
+/* harmony import */ var common_Reducers_jsm__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(55);
+/* harmony import */ var _TopSiteForm__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(57);
+/* harmony import */ var _TopSite__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(43);
 function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
 
 
 
 
 
 
 
 
 
 
 
 
 
+
 function topSiteIconType(link) {
   if (link.customScreenshotURL) {
     return "custom_screenshot";
   }
 
   if (link.tippyTopIcon || link.faviconRef === "tippytop") {
     return "tippytop";
   }
@@ -5361,17 +5295,17 @@ function countTopSitesIconsTypes(topSite
     "screenshot_with_icon": 0,
     "screenshot": 0,
     "tippytop": 0,
     "rich_icon": 0,
     "no_image": 0
   });
 }
 
-class _TopSites extends react__WEBPACK_IMPORTED_MODULE_6___default.a.PureComponent {
+class _TopSites extends react__WEBPACK_IMPORTED_MODULE_7___default.a.PureComponent {
   constructor(props) {
     super(props);
     this.onEditFormClose = this.onEditFormClose.bind(this);
     this.onSearchShortcutsFormClose = this.onSearchShortcutsFormClose.bind(this);
   }
   /**
    * Dispatch session statistics about the quality of TopSites icons and pinned count.
    */
@@ -5395,17 +5329,17 @@ class _TopSites extends react__WEBPACK_I
   }
   /**
    * Return the TopSites that are visible based on prefs and window width.
    */
 
 
   _getVisibleTopSites() {
     // We hide 2 sites per row when not in the wide layout.
-    let sitesPerRow = common_Reducers_jsm__WEBPACK_IMPORTED_MODULE_8__["TOP_SITES_MAX_SITES_PER_ROW"]; // $break-point-widest = 1072px (from _variables.scss)
+    let sitesPerRow = common_Reducers_jsm__WEBPACK_IMPORTED_MODULE_9__["TOP_SITES_MAX_SITES_PER_ROW"]; // $break-point-widest = 1072px (from _variables.scss)
 
     if (!global.matchMedia(`(min-width: 1072px)`).matches) {
       sitesPerRow -= 2;
     }
 
     return this.props.TopSites.rows.slice(0, this.props.TopSitesRows * sitesPerRow);
   }
 
@@ -5446,81 +5380,77 @@ class _TopSites extends react__WEBPACK_I
       showSearchShortcutsForm
     } = props.TopSites;
     const extraMenuOptions = ["AddTopSite"];
 
     if (props.Prefs.values["improvesearch.topSiteSearchShortcuts"]) {
       extraMenuOptions.push("AddSearchShortcut");
     }
 
-    return react__WEBPACK_IMPORTED_MODULE_6___default.a.createElement(content_src_components_ComponentPerfTimer_ComponentPerfTimer__WEBPACK_IMPORTED_MODULE_3__["ComponentPerfTimer"], {
+    return react__WEBPACK_IMPORTED_MODULE_7___default.a.createElement(content_src_components_ComponentPerfTimer_ComponentPerfTimer__WEBPACK_IMPORTED_MODULE_3__["ComponentPerfTimer"], {
       id: "topsites",
       initialized: props.TopSites.initialized,
       dispatch: props.dispatch
-    }, react__WEBPACK_IMPORTED_MODULE_6___default.a.createElement(content_src_components_CollapsibleSection_CollapsibleSection__WEBPACK_IMPORTED_MODULE_2__["CollapsibleSection"], {
+    }, react__WEBPACK_IMPORTED_MODULE_7___default.a.createElement(content_src_components_CollapsibleSection_CollapsibleSection__WEBPACK_IMPORTED_MODULE_2__["CollapsibleSection"], {
       className: "top-sites",
       icon: "topsites",
       id: "topsites",
       title: this.props.title || {
         id: "header_top_sites"
       },
       extraMenuOptions: extraMenuOptions,
       showPrefName: "feeds.topsites",
       eventSource: _TopSitesConstants__WEBPACK_IMPORTED_MODULE_1__["TOP_SITES_SOURCE"],
       collapsed: props.TopSites.pref ? props.TopSites.pref.collapsed : undefined,
       isFixed: props.isFixed,
       isFirst: props.isFirst,
       isLast: props.isLast,
       dispatch: props.dispatch
-    }, react__WEBPACK_IMPORTED_MODULE_6___default.a.createElement(_TopSite__WEBPACK_IMPORTED_MODULE_10__["TopSiteList"], {
+    }, react__WEBPACK_IMPORTED_MODULE_7___default.a.createElement(_TopSite__WEBPACK_IMPORTED_MODULE_11__["TopSiteList"], {
       TopSites: props.TopSites,
       TopSitesRows: props.TopSitesRows,
       dispatch: props.dispatch,
       intl: props.intl,
       topSiteIconType: topSiteIconType
-    }), react__WEBPACK_IMPORTED_MODULE_6___default.a.createElement("div", {
+    }), react__WEBPACK_IMPORTED_MODULE_7___default.a.createElement("div", {
       className: "edit-topsites-wrapper"
-    }, editForm && react__WEBPACK_IMPORTED_MODULE_6___default.a.createElement("div", {
+    }, editForm && react__WEBPACK_IMPORTED_MODULE_7___default.a.createElement("div", {
       className: "edit-topsites"
-    }, react__WEBPACK_IMPORTED_MODULE_6___default.a.createElement("div", {
-      className: "modal-overlay",
-      onClick: this.onEditFormClose,
-      role: "presentation"
-    }), react__WEBPACK_IMPORTED_MODULE_6___default.a.createElement("div", {
-      className: "modal"
-    }, react__WEBPACK_IMPORTED_MODULE_6___default.a.createElement(_TopSiteForm__WEBPACK_IMPORTED_MODULE_9__["TopSiteForm"], _extends({
+    }, react__WEBPACK_IMPORTED_MODULE_7___default.a.createElement(_asrouter_components_ModalOverlay_ModalOverlay__WEBPACK_IMPORTED_MODULE_6__["ModalOverlayWrapper"], {
+      unstyled: true,
+      onClose: this.onEditFormClose,
+      innerClassName: "modal"
+    }, react__WEBPACK_IMPORTED_MODULE_7___default.a.createElement(_TopSiteForm__WEBPACK_IMPORTED_MODULE_10__["TopSiteForm"], _extends({
       site: props.TopSites.rows[editForm.index],
       onClose: this.onEditFormClose,
       dispatch: this.props.dispatch,
       intl: this.props.intl
-    }, editForm)))), showSearchShortcutsForm && react__WEBPACK_IMPORTED_MODULE_6___default.a.createElement("div", {
+    }, editForm)))), showSearchShortcutsForm && react__WEBPACK_IMPORTED_MODULE_7___default.a.createElement("div", {
       className: "edit-search-shortcuts"
-    }, react__WEBPACK_IMPORTED_MODULE_6___default.a.createElement("div", {
-      className: "modal-overlay",
-      onClick: this.onSearchShortcutsFormClose,
-      role: "presentation"
-    }), react__WEBPACK_IMPORTED_MODULE_6___default.a.createElement("div", {
-      className: "modal"
-    }, react__WEBPACK_IMPORTED_MODULE_6___default.a.createElement(_SearchShortcutsForm__WEBPACK_IMPORTED_MODULE_7__["SearchShortcutsForm"], {
+    }, react__WEBPACK_IMPORTED_MODULE_7___default.a.createElement(_asrouter_components_ModalOverlay_ModalOverlay__WEBPACK_IMPORTED_MODULE_6__["ModalOverlayWrapper"], {
+      unstyled: true,
+      onClose: this.onSearchShortcutsFormClose,
+      innerClassName: "modal"
+    }, react__WEBPACK_IMPORTED_MODULE_7___default.a.createElement(_SearchShortcutsForm__WEBPACK_IMPORTED_MODULE_8__["SearchShortcutsForm"], {
       TopSites: props.TopSites,
       onClose: this.onSearchShortcutsFormClose,
       dispatch: this.props.dispatch
     }))))));
   }
 
 }
 const TopSites = Object(react_redux__WEBPACK_IMPORTED_MODULE_4__["connect"])(state => ({
   TopSites: state.TopSites,
   Prefs: state.Prefs,
   TopSitesRows: state.Prefs.values.topSitesRows
 }))(Object(react_intl__WEBPACK_IMPORTED_MODULE_5__["injectIntl"])(_TopSites));
 /* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(1)))
 
 /***/ }),
-/* 40 */
+/* 39 */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "TOP_SITES_SOURCE", function() { return TOP_SITES_SOURCE; });
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "TOP_SITES_CONTEXT_MENU_OPTIONS", function() { return TOP_SITES_CONTEXT_MENU_OPTIONS; });
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "TOP_SITES_SEARCH_SHORTCUTS_CONTEXT_MENU_OPTIONS", function() { return TOP_SITES_SEARCH_SHORTCUTS_CONTEXT_MENU_OPTIONS; });
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "MIN_RICH_FAVICON_SIZE", function() { return MIN_RICH_FAVICON_SIZE; });
@@ -5530,25 +5460,25 @@ const TOP_SITES_CONTEXT_MENU_OPTIONS = [
 
 const TOP_SITES_SEARCH_SHORTCUTS_CONTEXT_MENU_OPTIONS = ["CheckPinTopSite", "Separator", "BlockUrl"]; // minimum size necessary to show a rich icon instead of a screenshot
 
 const MIN_RICH_FAVICON_SIZE = 96; // minimum size necessary to show any icon in the top left corner with a screenshot
 
 const MIN_CORNER_FAVICON_SIZE = 16;
 
 /***/ }),
-/* 41 */
+/* 40 */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ComponentPerfTimer", function() { return ComponentPerfTimer; });
 /* harmony import */ var common_Actions_jsm__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(2);
-/* harmony import */ var common_PerfService_jsm__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(42);
-/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(11);
+/* harmony import */ var common_PerfService_jsm__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(41);
+/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(10);
 /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_2__);
 
 
  // Currently record only a fixed set of sections. This will prevent data
 // from custom sections from showing up or from topstories.
 
 const RECORDED_SECTIONS = ["highlights", "topsites"];
 class ComponentPerfTimer extends react__WEBPACK_IMPORTED_MODULE_2___default.a.Component {
@@ -5707,17 +5637,17 @@ class ComponentPerfTimer extends react__
     }
 
     return this.props.children;
   }
 
 }
 
 /***/ }),
-/* 42 */
+/* 41 */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "_PerfService", function() { return _PerfService; });
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "perfService", function() { return perfService; });
 
 
@@ -5733,29 +5663,20 @@ if (typeof ChromeUtils !== "undefined") 
 let usablePerfObj;
 /* istanbul ignore else */
 // eslint-disable-next-line block-scoped-var
 
 if (typeof Services !== "undefined") {
   // Borrow the high-resolution timer from the hidden window....
   // eslint-disable-next-line block-scoped-var
   usablePerfObj = Services.appShell.hiddenDOMWindow.performance;
-} else if (typeof performance !== "undefined") {
+} else {
   // we must be running in content space
   // eslint-disable-next-line no-undef
   usablePerfObj = performance;
-} else {
-  // This is a dummy object so this file doesn't crash in the node prerendering
-  // task.
-  usablePerfObj = {
-    now() {},
-
-    mark() {}
-
-  };
 }
 
 function _PerfService(options) {
   // For testing, so that we can use a fake Window.performance object with
   // known state.
   if (options && options.performanceObj) {
     this._perf = options.performanceObj;
   } else {
@@ -5845,29 +5766,29 @@ function _PerfService(options) {
     let mostRecentEntry = entries[entries.length - 1];
     return this._perf.timeOrigin + mostRecentEntry.startTime;
   }
 
 };
 var perfService = new _PerfService();
 
 /***/ }),
-/* 43 */
+/* 42 */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SelectableSearchShortcut", function() { return SelectableSearchShortcut; });
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SearchShortcutsForm", function() { return SearchShortcutsForm; });
 /* harmony import */ var common_Actions_jsm__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(2);
 /* harmony import */ var react_intl__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(4);
 /* harmony import */ var react_intl__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(react_intl__WEBPACK_IMPORTED_MODULE_1__);
-/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(11);
+/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(10);
 /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_2__);
-/* harmony import */ var _TopSitesConstants__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(40);
+/* harmony import */ var _TopSitesConstants__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(39);
 
 
 
 
 class SelectableSearchShortcut extends react__WEBPACK_IMPORTED_MODULE_2___default.a.PureComponent {
   render() {
     const {
       shortcut,
@@ -6039,35 +5960,35 @@ class SearchShortcutsForm extends react_
     }, react__WEBPACK_IMPORTED_MODULE_2___default.a.createElement(react_intl__WEBPACK_IMPORTED_MODULE_1__["FormattedMessage"], {
       id: "topsites_form_save_button"
     }))));
   }
 
 }
 
 /***/ }),
-/* 44 */
+/* 43 */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "TopSiteLink", function() { return TopSiteLink; });
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "TopSite", function() { return TopSite; });
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "TopSitePlaceholder", function() { return TopSitePlaceholder; });
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "_TopSiteList", function() { return _TopSiteList; });
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "TopSiteList", function() { return TopSiteList; });
 /* harmony import */ var common_Actions_jsm__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(2);
 /* harmony import */ var react_intl__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(4);
 /* harmony import */ var react_intl__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(react_intl__WEBPACK_IMPORTED_MODULE_1__);
-/* harmony import */ var _TopSitesConstants__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(40);
-/* harmony import */ var content_src_components_LinkMenu_LinkMenu__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(30);
-/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(11);
+/* harmony import */ var _TopSitesConstants__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(39);
+/* harmony import */ var content_src_components_LinkMenu_LinkMenu__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(29);
+/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(10);
 /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_4__);
-/* harmony import */ var content_src_lib_screenshot_utils__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(45);
-/* harmony import */ var common_Reducers_jsm__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(57);
+/* harmony import */ var content_src_lib_screenshot_utils__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(44);
+/* harmony import */ var common_Reducers_jsm__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(55);
 function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
 
 
 
 
 
 
 
@@ -6698,17 +6619,17 @@ class _TopSiteList extends react__WEBPAC
       className: `top-sites-list${this.state.draggedSite ? " dnd-active" : ""}`
     }, topSitesUI);
   }
 
 }
 const TopSiteList = Object(react_intl__WEBPACK_IMPORTED_MODULE_1__["injectIntl"])(_TopSiteList);
 
 /***/ }),
-/* 45 */
+/* 44 */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* WEBPACK VAR INJECTION */(function(global) {/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ScreenshotUtils", function() { return ScreenshotUtils; });
 /**
  * List of helper functions for screenshot-based images.
  *
@@ -6763,168 +6684,30 @@ const ScreenshotUtils = {
 
     return !remoteImage && !localImage;
   }
 
 };
 /* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(1)))
 
 /***/ }),
-/* 46 */
-/***/ (function(module, __webpack_exports__, __webpack_require__) {
-
-"use strict";
-__webpack_require__.r(__webpack_exports__);
-/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "_PrerenderData", function() { return _PrerenderData; });
-/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "PrerenderData", function() { return PrerenderData; });
-class _PrerenderData {
-  constructor(options) {
-    this.initialPrefs = options.initialPrefs;
-    this.initialSections = options.initialSections;
-
-    this._setValidation(options.validation);
-  }
-
-  get validation() {
-    return this._validation;
-  }
-
-  set validation(value) {
-    this._setValidation(value);
-  }
-
-  get invalidatingPrefs() {
-    return this._invalidatingPrefs;
-  } // This is needed so we can use it in the constructor
-
-
-  _setValidation(value = []) {
-    this._validation = value;
-    this._invalidatingPrefs = value.reduce((result, next) => {
-      if (typeof next === "string") {
-        result.push(next);
-        return result;
-      } else if (next && next.oneOf) {
-        return result.concat(next.oneOf);
-      } else if (next && next.indexedDB) {
-        return result.concat(next.indexedDB);
-      } else if (next && next.jsonPrefs) {
-        return result.concat(next.jsonPrefs);
-      }
-
-      throw new Error("Your validation configuration is not properly configured");
-    }, []);
-  }
-
-  _isPrefEnabled(prefObj) {
-    try {
-      let data = JSON.parse(prefObj);
-      return data && data.enabled ? true : false; // eslint-disable-line no-unneeded-ternary
-    } catch (e) {
-      return false;
-    }
-  }
-
-  arePrefsValid(getPref, indexedDBPrefs) {
-    for (const prefs of this.validation) {
-      // {oneOf: ["foo", "bar"]}
-      if (prefs && prefs.oneOf && !prefs.oneOf.some(name => getPref(name) === this.initialPrefs[name])) {
-        return false; // {indexedDB: ["foo", "bar"]}
-      } else if (indexedDBPrefs && prefs && prefs.indexedDB) {
-        const anyModifiedPrefs = prefs.indexedDB.some(prefName => indexedDBPrefs.some(pref => pref && pref[prefName]));
-
-        if (anyModifiedPrefs) {
-          return false;
-        } // {jsonPrefs: ["foo", "bar"]}
-
-      } else if (prefs && prefs.jsonPrefs) {
-        const isPrefModified = prefs.jsonPrefs.some(name => this._isPrefEnabled(getPref(name)) !== this.initialPrefs[name].enabled);
-
-        if (isPrefModified) {
-          return false;
-        } // "foo"
-
-      } else if (getPref(prefs) !== this.initialPrefs[prefs]) {
-        return false;
-      }
-    }
-
-    return true;
-  }
-
-}
-var PrerenderData = new _PrerenderData({
-  initialPrefs: {
-    "feeds.topsites": true,
-    "showSearch": true,
-    "topSitesRows": 1,
-    "feeds.section.topstories": true,
-    "feeds.section.highlights": true,
-    "sectionOrder": "topsites,topstories,highlights",
-    "collapsed": false,
-    "discoverystream.config": {
-      "enabled": false
-    }
-  },
-  // Prefs listed as invalidating will prevent the prerendered version
-  // of AS from being used if their value is something other than what is listed
-  // here. This is required because some preferences cause the page layout to be
-  // too different for the prerendered version to be used. Unfortunately, this
-  // will result in users who have modified some of their preferences not being
-  // able to get the benefits of prerendering.
-  validation: ["feeds.topsites", "showSearch", "topSitesRows", "sectionOrder", // This means if either of these are set to their default values,
-  // prerendering can be used.
-  {
-    oneOf: ["feeds.section.topstories", "feeds.section.highlights"]
-  }, // If any component has the following preference set to `true` it will
-  // invalidate the prerendered version.
-  {
-    indexedDB: ["collapsed"]
-  }, // For below prefs, parse value to check enabled property. If enabled property
-  // differs from initial prefs enabled value, prerendering cannot be used
-  {
-    jsonPrefs: ["discoverystream.config"]
-  }],
-  initialSections: [{
-    enabled: true,
-    icon: "pocket",
-    id: "topstories",
-    order: 1,
-    title: {
-      id: "header_recommended_by",
-      values: {
-        provider: "Pocket"
-      }
-    }
-  }, {
-    enabled: true,
-    id: "highlights",
-    icon: "highlights",
-    order: 2,
-    title: {
-      id: "header_highlights"
-    }
-  }]
-});
-
-/***/ }),
-/* 47 */
+/* 45 */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "_Search", function() { return _Search; });
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Search", function() { return Search; });
 /* harmony import */ var common_Actions_jsm__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(2);
 /* harmony import */ var react_intl__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(4);
 /* harmony import */ var react_intl__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(react_intl__WEBPACK_IMPORTED_MODULE_1__);
-/* harmony import */ var react_redux__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(26);
+/* harmony import */ var react_redux__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(25);
 /* harmony import */ var react_redux__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(react_redux__WEBPACK_IMPORTED_MODULE_2__);
-/* harmony import */ var content_src_lib_constants__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(13);
-/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(11);
+/* harmony import */ var content_src_lib_constants__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(12);
+/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(10);
 /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_4__);
 /* globals ContentSearchUIController */
 
 
 
 
 
 
@@ -7109,39 +6892,39 @@ class _Search extends react__WEBPACK_IMP
       ref: this.onInputMount
     })));
   }
 
 }
 const Search = Object(react_redux__WEBPACK_IMPORTED_MODULE_2__["connect"])()(Object(react_intl__WEBPACK_IMPORTED_MODULE_1__["injectIntl"])(_Search));
 
 /***/ }),
-/* 48 */
+/* 46 */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* WEBPACK VAR INJECTION */(function(global) {/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Section", function() { return Section; });
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SectionIntl", function() { return SectionIntl; });
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "_Sections", function() { return _Sections; });
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Sections", function() { return Sections; });
 /* harmony import */ var common_Actions_jsm__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(2);
-/* harmony import */ var content_src_components_Card_Card__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(58);
+/* harmony import */ var content_src_components_Card_Card__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(56);
 /* harmony import */ var react_intl__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(4);
 /* harmony import */ var react_intl__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(react_intl__WEBPACK_IMPORTED_MODULE_2__);
-/* harmony import */ var content_src_components_CollapsibleSection_CollapsibleSection__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(34);
-/* harmony import */ var content_src_components_ComponentPerfTimer_ComponentPerfTimer__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(41);
-/* harmony import */ var react_redux__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(26);
+/* harmony import */ var content_src_components_CollapsibleSection_CollapsibleSection__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(33);
+/* harmony import */ var content_src_components_ComponentPerfTimer_ComponentPerfTimer__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(40);
+/* harmony import */ var react_redux__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(25);
 /* harmony import */ var react_redux__WEBPACK_IMPORTED_MODULE_5___default = /*#__PURE__*/__webpack_require__.n(react_redux__WEBPACK_IMPORTED_MODULE_5__);
-/* harmony import */ var content_src_components_MoreRecommendations_MoreRecommendations__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(49);
-/* harmony import */ var content_src_components_PocketLoggedInCta_PocketLoggedInCta__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(50);
-/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(11);
+/* harmony import */ var content_src_components_MoreRecommendations_MoreRecommendations__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(47);
+/* harmony import */ var content_src_components_PocketLoggedInCta_PocketLoggedInCta__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(48);
+/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(10);
 /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_8___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_8__);
-/* harmony import */ var content_src_components_Topics_Topics__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(51);
-/* harmony import */ var content_src_components_TopSites_TopSites__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(39);
+/* harmony import */ var content_src_components_Topics_Topics__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(49);
+/* harmony import */ var content_src_components_TopSites_TopSites__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(38);
 function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
 
 
 
 
 
 
 
@@ -7480,25 +7263,25 @@ class _Sections extends react__WEBPACK_I
 }
 const Sections = Object(react_redux__WEBPACK_IMPORTED_MODULE_5__["connect"])(state => ({
   Sections: state.Sections,
   Prefs: state.Prefs
 }))(_Sections);
 /* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(1)))
 
 /***/ }),
-/* 49 */
+/* 47 */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "MoreRecommendations", function() { return MoreRecommendations; });
 /* harmony import */ var react_intl__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(4);
 /* harmony import */ var react_intl__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react_intl__WEBPACK_IMPORTED_MODULE_0__);
-/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(11);
+/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(10);
 /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_1__);
 
 
 class MoreRecommendations extends react__WEBPACK_IMPORTED_MODULE_1___default.a.PureComponent {
   render() {
     const {
       read_more_endpoint
     } = this.props;
@@ -7513,28 +7296,28 @@ class MoreRecommendations extends react_
     }
 
     return null;
   }
 
 }
 
 /***/ }),
-/* 50 */
+/* 48 */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "_PocketLoggedInCta", function() { return _PocketLoggedInCta; });
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "PocketLoggedInCta", function() { return PocketLoggedInCta; });
-/* harmony import */ var react_redux__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(26);
+/* harmony import */ var react_redux__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(25);
 /* harmony import */ var react_redux__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react_redux__WEBPACK_IMPORTED_MODULE_0__);
 /* harmony import */ var react_intl__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(4);
 /* harmony import */ var react_intl__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(react_intl__WEBPACK_IMPORTED_MODULE_1__);
-/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(11);
+/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(10);
 /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_2__);
 
 
 
 class _PocketLoggedInCta extends react__WEBPACK_IMPORTED_MODULE_2___default.a.PureComponent {
   render() {
     const {
       pocketCta
@@ -7556,26 +7339,26 @@ class _PocketLoggedInCta extends react__
   }
 
 }
 const PocketLoggedInCta = Object(react_redux__WEBPACK_IMPORTED_MODULE_0__["connect"])(state => ({
   Pocket: state.Pocket
 }))(_PocketLoggedInCta);
 
 /***/ }),
-/* 51 */
+/* 49 */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Topic", function() { return Topic; });
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Topics", function() { return Topics; });
 /* harmony import */ var react_intl__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(4);
 /* harmony import */ var react_intl__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react_intl__WEBPACK_IMPORTED_MODULE_0__);
-/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(11);
+/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(10);
 /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_1__);
 
 
 class Topic extends react__WEBPACK_IMPORTED_MODULE_1___default.a.PureComponent {
   render() {
     const {
       url,
       name
@@ -7601,24 +7384,24 @@ class Topics extends react__WEBPACK_IMPO
       url: t.url,
       name: t.name
     }))));
   }
 
 }
 
 /***/ }),
-/* 52 */
+/* 50 */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* WEBPACK VAR INJECTION */(function(global) {/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "DetectUserSessionStart", function() { return DetectUserSessionStart; });
 /* harmony import */ var common_Actions_jsm__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(2);
-/* harmony import */ var common_PerfService_jsm__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(42);
+/* harmony import */ var common_PerfService_jsm__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(41);
 
 
 const VISIBLE = "visible";
 const VISIBILITY_CHANGE_EVENT = "visibilitychange";
 class DetectUserSessionStart {
   constructor(store, options = {}) {
     this._store = store; // Overrides for testing
 
@@ -7680,31 +7463,31 @@ class DetectUserSessionStart {
       this.document.removeEventListener(VISIBILITY_CHANGE_EVENT, this._onVisibilityChange);
     }
   }
 
 }
 /* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(1)))
 
 /***/ }),
-/* 53 */
+/* 51 */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 
 // EXTERNAL MODULE: ./common/Actions.jsm
 var Actions = __webpack_require__(2);
 
 // EXTERNAL MODULE: external "React"
-var external_React_ = __webpack_require__(11);
+var external_React_ = __webpack_require__(10);
 var external_React_default = /*#__PURE__*/__webpack_require__.n(external_React_);
 
 // EXTERNAL MODULE: external "ReactDOM"
-var external_ReactDOM_ = __webpack_require__(16);
+var external_ReactDOM_ = __webpack_require__(15);
 var external_ReactDOM_default = /*#__PURE__*/__webpack_require__.n(external_ReactDOM_);
 
 // CONCATENATED MODULE: ./content-src/components/DiscoveryStreamComponents/DSImage/DSImage.jsx
 
 
 class DSImage_DSImage extends external_React_default.a.PureComponent {
   constructor(props) {
     super(props);
@@ -7818,17 +7601,17 @@ DSImage_DSImage.defaultProps = {
   // Additional classnames to append to component
   optimize: true // Measure parent container to request exact sizes
 
 };
 // EXTERNAL MODULE: external "ReactIntl"
 var external_ReactIntl_ = __webpack_require__(4);
 
 // EXTERNAL MODULE: ./content-src/components/LinkMenu/LinkMenu.jsx
-var LinkMenu = __webpack_require__(30);
+var LinkMenu = __webpack_require__(29);
 
 // CONCATENATED MODULE: ./content-src/components/DiscoveryStreamComponents/DSLinkMenu/DSLinkMenu.jsx
 
 
 
 class DSLinkMenu_DSLinkMenu extends external_React_default.a.PureComponent {
   constructor(props) {
     super(props);
@@ -7912,17 +7695,17 @@ class DSLinkMenu_DSLinkMenu extends exte
         bookmarkGuid: this.props.bookmarkGuid
       }
     }));
   }
 
 }
 const DSLinkMenu = Object(external_ReactIntl_["injectIntl"])(DSLinkMenu_DSLinkMenu);
 // EXTERNAL MODULE: ./content-src/components/DiscoveryStreamImpressionStats/ImpressionStats.jsx
-var ImpressionStats = __webpack_require__(33);
+var ImpressionStats = __webpack_require__(32);
 
 // CONCATENATED MODULE: ./content-src/components/DiscoveryStreamComponents/SafeAnchor/SafeAnchor.jsx
 
 
 class SafeAnchor_SafeAnchor extends external_React_default.a.PureComponent {
   constructor(props) {
     super(props);
     this.onClick = this.onClick.bind(this);
@@ -8155,20 +7938,20 @@ class CardGrid_CardGrid extends external
 
 }
 CardGrid_CardGrid.defaultProps = {
   border: `border`,
   items: 4 // Number of stories to display
 
 };
 // EXTERNAL MODULE: ./content-src/components/CollapsibleSection/CollapsibleSection.jsx
-var CollapsibleSection = __webpack_require__(34);
+var CollapsibleSection = __webpack_require__(33);
 
 // EXTERNAL MODULE: external "ReactRedux"
-var external_ReactRedux_ = __webpack_require__(26);
+var external_ReactRedux_ = __webpack_require__(25);
 
 // CONCATENATED MODULE: ./content-src/components/DiscoveryStreamComponents/DSMessage/DSMessage.jsx
 
 
 class DSMessage_DSMessage extends external_React_default.a.PureComponent {
   render() {
     return external_React_default.a.createElement("div", {
       className: "ds-message"
@@ -8756,17 +8539,17 @@ const selectLayoutRender = (state, prefs
   }
 
   return {
     spocsFill,
     layoutRender
   };
 };
 // EXTERNAL MODULE: ./content-src/components/TopSites/TopSites.jsx
-var TopSites = __webpack_require__(39);
+var TopSites = __webpack_require__(38);
 
 // CONCATENATED MODULE: ./content-src/components/DiscoveryStreamComponents/TopSites/TopSites.jsx
 
 
 
 class TopSites_TopSites extends external_React_default.a.PureComponent {
   render() {
     const header = this.props.header || {};
@@ -9069,28 +8852,825 @@ class DiscoveryStreamBase_DiscoveryStrea
 }
 const DiscoveryStreamBase = Object(external_ReactRedux_["connect"])(state => ({
   DiscoveryStream: state.DiscoveryStream,
   Prefs: state.Prefs,
   Sections: state.Sections
 }))(DiscoveryStreamBase_DiscoveryStreamBase);
 
 /***/ }),
-/* 54 */
+/* 52 */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 
 // EXTERNAL MODULE: external "React"
-var external_React_ = __webpack_require__(11);
+var external_React_ = __webpack_require__(10);
+
+// EXTERNAL MODULE: external "PropTypes"
+var external_PropTypes_ = __webpack_require__(11);
+var external_PropTypes_default = /*#__PURE__*/__webpack_require__.n(external_PropTypes_);
+
+// CONCATENATED MODULE: ./node_modules/fluent-sequence/src/map_sync.js
+/*
+ * Synchronously map an identifier or an array of identifiers to the best
+ * `FluentBundle` instance(s).
+ *
+ * @param {Iterable} iterable
+ * @param {string|Array<string>} ids
+ * @returns {FluentBundle|Array<FluentBundle>}
+ */
+function mapBundleSync(iterable, ids) {
+  if (!Array.isArray(ids)) {
+    return getBundleForId(iterable, ids);
+  }
+
+  return ids.map(
+    id => getBundleForId(iterable, id)
+  );
+}
+
+/*
+ * Find the best `FluentBundle` with the translation for `id`.
+ */
+function getBundleForId(iterable, id) {
+  for (const bundle of iterable) {
+    if (bundle.hasMessage(id)) {
+      return bundle;
+    }
+  }
+
+  return null;
+}
+
+// CONCATENATED MODULE: ./node_modules/fluent-sequence/src/map_async.js
+/*
+ * Asynchronously map an identifier or an array of identifiers to the best
+ * `FluentBundle` instance(s).
+ *
+ * @param {AsyncIterable} iterable
+ * @param {string|Array<string>} ids
+ * @returns {Promise<FluentBundle|Array<FluentBundle>>}
+ */
+async function mapBundleAsync(iterable, ids) {
+  if (!Array.isArray(ids)) {
+    for await (const bundle of iterable) {
+      if (bundle.hasMessage(ids)) {
+        return bundle;
+      }
+    }
+  }
+
+  let remainingCount = ids.length;
+  const foundBundles = new Array(remainingCount).fill(null);
+
+  for await (const bundle of iterable) {
+    for (const [index, id] of ids.entries()) {
+      if (!foundBundles[index] && bundle.hasMessage(id)) {
+        foundBundles[index] = bundle;
+        remainingCount--;
+      }
+
+      // Return early when all ids have been mapped to contexts.
+      if (remainingCount === 0) {
+        return foundBundles;
+      }
+    }
+  }
+
+  return foundBundles;
+}
+
+// CONCATENATED MODULE: ./node_modules/fluent-sequence/src/index.js
+/*
+ * @module fluent-sequence
+ * @overview Manage ordered sequences of FluentBundles.
+ */
+
+
+
+
+// CONCATENATED MODULE: ./node_modules/cached-iterable/src/cached_iterable.mjs
+/*
+ * Base CachedIterable class.
+ */
+class CachedIterable extends Array {
+    /**
+     * Create a `CachedIterable` instance from an iterable or, if another
+     * instance of `CachedIterable` is passed, return it without any
+     * modifications.
+     *
+     * @param {Iterable} iterable
+     * @returns {CachedIterable}
+     */
+    static from(iterable) {
+        if (iterable instanceof this) {
+            return iterable;
+        }
+
+        return new this(iterable);
+    }
+}
+
+// CONCATENATED MODULE: ./node_modules/cached-iterable/src/cached_sync_iterable.mjs
+
+
+/*
+ * CachedSyncIterable caches the elements yielded by an iterable.
+ *
+ * It can be used to iterate over an iterable many times without depleting the
+ * iterable.
+ */
+class cached_sync_iterable_CachedSyncIterable extends CachedIterable {
+    /**
+     * Create an `CachedSyncIterable` instance.
+     *
+     * @param {Iterable} iterable
+     * @returns {CachedSyncIterable}
+     */
+    constructor(iterable) {
+        super();
+
+        if (Symbol.iterator in Object(iterable)) {
+            this.iterator = iterable[Symbol.iterator]();
+        } else {
+            throw new TypeError("Argument must implement the iteration protocol.");
+        }
+    }
+
+    [Symbol.iterator]() {
+        const cached = this;
+        let cur = 0;
+
+        return {
+            next() {
+                if (cached.length <= cur) {
+                    cached.push(cached.iterator.next());
+                }
+                return cached[cur++];
+            }
+        };
+    }
+
+    /**
+     * This method allows user to consume the next element from the iterator
+     * into the cache.
+     *
+     * @param {number} count - number of elements to consume
+     */
+    touchNext(count = 1) {
+        let idx = 0;
+        while (idx++ < count) {
+            const last = this[this.length - 1];
+            if (last && last.done) {
+                break;
+            }
+            this.push(this.iterator.next());
+        }
+        // Return the last cached {value, done} object to allow the calling
+        // code to decide if it needs to call touchNext again.
+        return this[this.length - 1];
+    }
+}
+
+// CONCATENATED MODULE: ./node_modules/cached-iterable/src/cached_async_iterable.mjs
+
+
+/*
+ * CachedAsyncIterable caches the elements yielded by an async iterable.
+ *
+ * It can be used to iterate over an iterable many times without depleting the
+ * iterable.
+ */
+class cached_async_iterable_CachedAsyncIterable extends CachedIterable {
+    /**
+     * Create an `CachedAsyncIterable` instance.
+     *
+     * @param {Iterable} iterable
+     * @returns {CachedAsyncIterable}
+     */
+    constructor(iterable) {
+        super();
+
+        if (Symbol.asyncIterator in Object(iterable)) {
+            this.iterator = iterable[Symbol.asyncIterator]();
+        } else if (Symbol.iterator in Object(iterable)) {
+            this.iterator = iterable[Symbol.iterator]();
+        } else {
+            throw new TypeError("Argument must implement the iteration protocol.");
+        }
+    }
+
+    /**
+     * Synchronous iterator over the cached elements.
+     *
+     * Return a generator object implementing the iterator protocol over the
+     * cached elements of the original (async or sync) iterable.
+     */
+    [Symbol.iterator]() {
+        const cached = this;
+        let cur = 0;
+
+        return {
+            next() {
+                if (cached.length === cur) {
+                    return {value: undefined, done: true};
+                }
+                return cached[cur++];
+            }
+        };
+    }
+
+    /**
+     * Asynchronous iterator caching the yielded elements.
+     *
+     * Elements yielded by the original iterable will be cached and available
+     * synchronously. Returns an async generator object implementing the
+     * iterator protocol over the elements of the original (async or sync)
+     * iterable.
+     */
+    [Symbol.asyncIterator]() {
+        const cached = this;
+        let cur = 0;
+
+        return {
+            async next() {
+                if (cached.length <= cur) {
+                    cached.push(await cached.iterator.next());
+                }
+                return cached[cur++];
+            }
+        };
+    }
+
+    /**
+     * This method allows user to consume the next element from the iterator
+     * into the cache.
+     *
+     * @param {number} count - number of elements to consume
+     */
+    async touchNext(count = 1) {
+        let idx = 0;
+        while (idx++ < count) {
+            const last = this[this.length - 1];
+            if (last && last.done) {
+                break;
+            }
+            this.push(await this.iterator.next());
+        }
+        // Return the last cached {value, done} object to allow the calling
+        // code to decide if it needs to call touchNext again.
+        return this[this.length - 1];
+    }
+}
+
+// CONCATENATED MODULE: ./node_modules/cached-iterable/src/index.mjs
+
+
+
+// CONCATENATED MODULE: ./node_modules/fluent-react/src/localization.js
+
+
+/*
+ * `ReactLocalization` handles translation formatting and fallback.
+ *
+ * The current negotiated fallback chain of languages is stored in the
+ * `ReactLocalization` instance in form of an iterable of `FluentBundle`
+ * instances.  This iterable is used to find the best existing translation for
+ * a given identifier.
+ *
+ * `Localized` components must subscribe to the changes of the
+ * `ReactLocalization`'s fallback chain.  When the fallback chain changes (the
+ * `bundles` iterable is set anew), all subscribed compontent must relocalize.
+ *
+ * The `ReactLocalization` class instances are exposed to `Localized` elements
+ * via the `LocalizationProvider` component.
+ */
+
+class localization_ReactLocalization {
+  constructor(bundles) {
+    this.bundles = cached_sync_iterable_CachedSyncIterable.from(bundles);
+    this.subs = new Set();
+  }
+  /*
+   * Subscribe a `Localized` component to changes of `bundles`.
+   */
+
+
+  subscribe(comp) {
+    this.subs.add(comp);
+  }
+  /*
+   * Unsubscribe a `Localized` component from `bundles` changes.
+   */
+
+
+  unsubscribe(comp) {
+    this.subs.delete(comp);
+  }
+  /*
+   * Set a new `bundles` iterable and trigger the retranslation.
+   */
+
+
+  setBundles(bundles) {
+    this.bundles = cached_sync_iterable_CachedSyncIterable.from(bundles); // Update all subscribed Localized components.
+
+    this.subs.forEach(comp => comp.relocalize());
+  }
+
+  getBundle(id) {
+    return mapBundleSync(this.bundles, id);
+  }
+  /*
+   * Find a translation by `id` and format it to a string using `args`.
+   */
+
+
+  getString(id, args, fallback) {
+    const bundle = this.getBundle(id);
+
+    if (bundle === null) {
+      return fallback || id;
+    }
+
+    const msg = bundle.getMessage(id);
+    return bundle.format(msg, args);
+  }
+
+}
+function isReactLocalization(props, propName) {
+  const prop = props[propName];
+
+  if (prop instanceof localization_ReactLocalization) {
+    return null;
+  }
+
+  return new Error(`The ${propName} context field must be an instance of ReactLocalization.`);
+}
+// CONCATENATED MODULE: ./node_modules/fluent-react/src/markup.js
+/* eslint-env browser */
+let cachedParseMarkup; // We use a function creator to make the reference to `document` lazy. At the
+// same time, it's eager enough to throw in <LocalizationProvider> as soon as
+// it's first mounted which reduces the risk of this error making it to the
+// runtime without developers noticing it in development.
+
+function createParseMarkup() {
+  if (typeof document === "undefined") {
+    // We can't use <template> to sanitize translations.
+    throw new Error("`document` is undefined. Without it, translations cannot " + "be safely sanitized. Consult the documentation at " + "https://github.com/projectfluent/fluent.js/wiki/React-Overlays.");
+  }
+
+  if (!cachedParseMarkup) {
+    const template = document.createElement("template");
+
+    cachedParseMarkup = function parseMarkup(str) {
+      template.innerHTML = str;
+      return Array.from(template.content.childNodes);
+    };
+  }
+
+  return cachedParseMarkup;
+}
+// CONCATENATED MODULE: ./node_modules/fluent-react/src/provider.js
+
+
+
+
+/*
+ * The Provider component for the `ReactLocalization` class.
+ *
+ * Exposes a `ReactLocalization` instance to all descendants via React's
+ * context feature.  It makes translations available to all localizable
+ * elements in the descendant's render tree without the need to pass them
+ * explicitly.
+ *
+ *     <LocalizationProvider bundles={…}>
+ *         …
+ *     </LocalizationProvider>
+ *
+ * The `LocalizationProvider` component takes one prop: `bundles`.  It should
+ * be an iterable of `FluentBundle` instances in order of the user's
+ * preferred languages.  The `FluentBundle` instances will be used by
+ * `ReactLocalization` to format translations.  If a translation is missing in
+ * one instance, `ReactLocalization` will fall back to the next one.
+ */
+
+class provider_LocalizationProvider extends external_React_["Component"] {
+  constructor(props) {
+    super(props);
+    const {
+      bundles,
+      parseMarkup
+    } = props;
+
+    if (bundles === undefined) {
+      throw new Error("LocalizationProvider must receive the bundles prop.");
+    }
+
+    if (!bundles[Symbol.iterator]) {
+      throw new Error("The bundles prop must be an iterable.");
+    }
+
+    this.l10n = new localization_ReactLocalization(bundles);
+    this.parseMarkup = parseMarkup || createParseMarkup();
+  }
+
+  getChildContext() {
+    return {
+      l10n: this.l10n,
+      parseMarkup: this.parseMarkup
+    };
+  }
+
+  componentWillReceiveProps(next) {
+    const {
+      bundles
+    } = next;
+
+    if (bundles !== this.props.bundles) {
+      this.l10n.setBundles(bundles);
+    }
+  }
+
+  render() {
+    return external_React_["Children"].only(this.props.children);
+  }
+
+}
+provider_LocalizationProvider.childContextTypes = {
+  l10n: isReactLocalization,
+  parseMarkup: external_PropTypes_default.a.func
+};
+provider_LocalizationProvider.propTypes = {
+  children: external_PropTypes_default.a.element.isRequired,
+  bundles: isIterable,
+  parseMarkup: external_PropTypes_default.a.func
+};
+
+function isIterable(props, propName, componentName) {
+  const prop = props[propName];
+
+  if (Symbol.iterator in Object(prop)) {
+    return null;
+  }
+
+  return new Error(`The ${propName} prop supplied to ${componentName} must be an iterable.`);
+}
+// CONCATENATED MODULE: ./node_modules/fluent-react/src/with_localization.js
+
+
+function withLocalization(Inner) {
+  class WithLocalization extends external_React_["Component"] {
+    componentDidMount() {
+      const {
+        l10n
+      } = this.context;
+
+      if (l10n) {
+        l10n.subscribe(this);
+      }
+    }
+
+    componentWillUnmount() {
+      const {
+        l10n
+      } = this.context;
+
+      if (l10n) {
+        l10n.unsubscribe(this);
+      }
+    }
+    /*
+     * Rerender this component in a new language.
+     */
+
+
+    relocalize() {
+      // When the `ReactLocalization`'s fallback chain changes, update the
+      // component.
+      this.forceUpdate();
+    }
+    /*
+     * Find a translation by `id` and format it to a string using `args`.
+     */
+
+
+    getString(id, args, fallback) {
+      const {
+        l10n
+      } = this.context;
+
+      if (!l10n) {
+        return fallback || id;
+      }
+
+      return l10n.getString(id, args, fallback);
+    }
+
+    render() {
+      return Object(external_React_["createElement"])(Inner, Object.assign( // getString needs to be re-bound on updates to trigger a re-render
+      {
+        getString: (...args) => this.getString(...args)
+      }, this.props));
+    }
+
+  }
+
+  WithLocalization.displayName = `WithLocalization(${displayName(Inner)})`;
+  WithLocalization.contextTypes = {
+    l10n: isReactLocalization
+  };
+  return WithLocalization;
+}
+
+function displayName(component) {
+  return component.displayName || component.name || "Component";
+}
+// CONCATENATED MODULE: ./node_modules/fluent-react/vendor/omittedCloseTags.js
+/**
+ * Copyright (c) 2013-present, Facebook, Inc.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in this directory.
+ */
+// For HTML, certain tags should omit their close tag. We keep a whitelist for
+// those special-case tags.
+var omittedCloseTags = {
+  area: true,
+  base: true,
+  br: true,
+  col: true,
+  embed: true,
+  hr: true,
+  img: true,
+  input: true,
+  keygen: true,
+  link: true,
+  meta: true,
+  param: true,
+  source: true,
+  track: true,
+  wbr: true // NOTE: menuitem's close tag should be omitted, but that causes problems.
+
+};
+/* harmony default export */ var vendor_omittedCloseTags = (omittedCloseTags);
+// CONCATENATED MODULE: ./node_modules/fluent-react/vendor/voidElementTags.js
+/**
+ * Copyright (c) 2013-present, Facebook, Inc.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in this directory.
+ */
+ // For HTML, certain tags cannot have children. This has the same purpose as
+// `omittedCloseTags` except that `menuitem` should still have its closing tag.
+
+var voidElementTags = {
+  menuitem: true,
+  ...vendor_omittedCloseTags
+};
+/* harmony default export */ var vendor_voidElementTags = (voidElementTags);
+// CONCATENATED MODULE: ./node_modules/fluent-react/src/localized.js
+
+
+
+ // Match the opening angle bracket (<) in HTML tags, and HTML entities like
+// &amp;, &#0038;, &#x0026;.
+
+const reMarkup = /<|&#?\w+;/;
+/*
+ * Prepare props passed to `Localized` for formatting.
+ */
+
+function toArguments(props) {
+  const args = {};
+  const elems = {};
+
+  for (const [propname, propval] of Object.entries(props)) {
+    if (propname.startsWith("$")) {
+      const name = propname.substr(1);
+      args[name] = propval;
+    } else if (Object(external_React_["isValidElement"])(propval)) {
+      // We'll try to match localNames of elements found in the translation with
+      // names of elements passed as props. localNames are always lowercase.
+      const name = propname.toLowerCase();
+      elems[name] = propval;
+    }
+  }
+
+  return [args, elems];
+}
+/*
+ * The `Localized` class renders its child with translated props and children.
+ *
+ *     <Localized id="hello-world">
+ *         <p>{'Hello, world!'}</p>
+ *     </Localized>
+ *
+ * The `id` prop should be the unique identifier of the translation.  Any
+ * attributes found in the translation will be applied to the wrapped element.
+ *
+ * Arguments to the translation can be passed as `$`-prefixed props on
+ * `Localized`.
+ *
+ *     <Localized id="hello-world" $username={name}>
+ *         <p>{'Hello, { $username }!'}</p>
+ *     </Localized>
+ *
+ *  It's recommended that the contents of the wrapped component be a string
+ *  expression.  The string will be used as the ultimate fallback if no
+ *  translation is available.  It also makes it easy to grep for strings in the
+ *  source code.
+ */
+
+
+class localized_Localized extends external_React_["Component"] {
+  componentDidMount() {
+    const {
+      l10n
+    } = this.context;
+
+    if (l10n) {
+      l10n.subscribe(this);
+    }
+  }
+
+  componentWillUnmount() {
+    const {
+      l10n
+    } = this.context;
+
+    if (l10n) {
+      l10n.unsubscribe(this);
+    }
+  }
+  /*
+   * Rerender this component in a new language.
+   */
+
+
+  relocalize() {
+    // When the `ReactLocalization`'s fallback chain changes, update the
+    // component.
+    this.forceUpdate();
+  }
+
+  render() {
+    const {
+      l10n,
+      parseMarkup
+    } = this.context;
+    const {
+      id,
+      attrs,
+      children: elem
+    } = this.props; // Validate that the child element isn't an array
+
+    if (Array.isArray(elem)) {
+      throw new Error("<Localized/> expected to receive a single " + "React node child");
+    }
+
+    if (!l10n) {
+      // Use the wrapped component as fallback.
+      return elem;
+    }
+
+    const bundle = l10n.getBundle(id);
+
+    if (bundle === null) {
+      // Use the wrapped component as fallback.
+      return elem;
+    }
+
+    const msg = bundle.getMessage(id);
+    const [args, elems] = toArguments(this.props);
+    const messageValue = bundle.format(msg, args); // Check if the fallback is a valid element -- if not then it's not
+    // markup (e.g. nothing or a fallback string) so just use the
+    // formatted message value
+
+    if (!Object(external_React_["isValidElement"])(elem)) {
+      return messageValue;
+    } // The default is to forbid all message attributes. If the attrs prop exists
+    // on the Localized instance, only set message attributes which have been
+    // explicitly allowed by the developer.
+
+
+    if (attrs && msg.attrs) {
+      var localizedProps = {};
+
+      for (const [name, allowed] of Object.entries(attrs)) {
+        if (allowed && msg.attrs.hasOwnProperty(name)) {
+          localizedProps[name] = bundle.format(msg.attrs[name], args);
+        }
+      }
+    } // If the wrapped component is a known void element, explicitly dismiss the
+    // message value and do not pass it to cloneElement in order to avoid the
+    // "void element tags must neither have `children` nor use
+    // `dangerouslySetInnerHTML`" error.
+
+
+    if (elem.type in vendor_voidElementTags) {
+      return Object(external_React_["cloneElement"])(elem, localizedProps);
+    } // If the message has a null value, we're only interested in its attributes.
+    // Do not pass the null value to cloneElement as it would nuke all children
+    // of the wrapped component.
+
+
+    if (messageValue === null) {
+      return Object(external_React_["cloneElement"])(elem, localizedProps);
+    } // If the message value doesn't contain any markup nor any HTML entities,
+    // insert it as the only child of the wrapped component.
+
+
+    if (!reMarkup.test(messageValue)) {
+      return Object(external_React_["cloneElement"])(elem, localizedProps, messageValue);
+    } // If the message contains markup, parse it and try to match the children
+    // found in the translation with the props passed to this Localized.
+
+
+    const translationNodes = parseMarkup(messageValue);
+    const translatedChildren = translationNodes.map(childNode => {
+      if (childNode.nodeType === childNode.TEXT_NODE) {
+        return childNode.textContent;
+      } // If the child is not expected just take its textContent.
+
+
+      if (!elems.hasOwnProperty(childNode.localName)) {
+        return childNode.textContent;
+      }
+
+      const sourceChild = elems[childNode.localName]; // If the element passed as a prop to <Localized> is a known void element,
+      // explicitly dismiss any textContent which might have accidentally been
+      // defined in the translation to prevent the "void element tags must not
+      // have children" error.
+
+      if (sourceChild.type in vendor_voidElementTags) {
+        return sourceChild;
+      } // TODO Protect contents of elements wrapped in <Localized>
+      // https://github.com/projectfluent/fluent.js/issues/184
+      // TODO  Control localizable attributes on elements passed as props
+      // https://github.com/projectfluent/fluent.js/issues/185
+
+
+      return Object(external_React_["cloneElement"])(sourceChild, null, childNode.textContent);
+    });
+    return Object(external_React_["cloneElement"])(elem, localizedProps, ...translatedChildren);
+  }
+
+}
+localized_Localized.contextTypes = {
+  l10n: isReactLocalization,
+  parseMarkup: external_PropTypes_default.a.func
+};
+localized_Localized.propTypes = {
+  children: external_PropTypes_default.a.node
+};
+// CONCATENATED MODULE: ./node_modules/fluent-react/src/index.js
+/* concated harmony reexport LocalizationProvider */__webpack_require__.d(__webpack_exports__, "LocalizationProvider", function() { return provider_LocalizationProvider; });
+/* concated harmony reexport withLocalization */__webpack_require__.d(__webpack_exports__, "withLocalization", function() { return withLocalization; });
+/* concated harmony reexport Localized */__webpack_require__.d(__webpack_exports__, "Localized", function() { return localized_Localized; });
+/* concated harmony reexport ReactLocalization */__webpack_require__.d(__webpack_exports__, "ReactLocalization", function() { return localization_ReactLocalization; });
+/* concated harmony reexport isReactLocalization */__webpack_require__.d(__webpack_exports__, "isReactLocalization", function() { return isReactLocalization; });
+/*
+ * @module fluent-react
+ * @overview
+ *
+
+ * `fluent-react` provides React bindings for Fluent.  It takes advantage of
+ * React's Components system and the virtual DOM.  Translations are exposed to
+ * components via the provider pattern.
+ *
+ *     <LocalizationProvider bundles={…}>
+ *         <Localized id="hello-world">
+ *             <p>{'Hello, world!'}</p>
+ *         </Localized>
+ *     </LocalizationProvider>
+ *
+ * Consult the documentation of the `LocalizationProvider` and the `Localized`
+ * components for more information.
+ */
+
+
+
+
+
+/***/ }),
+/* 53 */
+/***/ (function(module, __webpack_exports__, __webpack_require__) {
+
+"use strict";
+__webpack_require__.r(__webpack_exports__);
+
+// EXTERNAL MODULE: external "React"
+var external_React_ = __webpack_require__(10);
 var external_React_default = /*#__PURE__*/__webpack_require__.n(external_React_);
 
 // EXTERNAL MODULE: ./content-src/asrouter/templates/EOYSnippet/EOYSnippet.schema.json
-var EOYSnippet_schema = __webpack_require__(20);
+var EOYSnippet_schema = __webpack_require__(19);
 
 // CONCATENATED MODULE: ./content-src/asrouter/components/Button/Button.jsx
 
 const ALLOWED_STYLE_TAGS = ["color", "backgroundColor"];
 const Button = props => {
   const style = {}; // Add allowed style tags from props, e.g. props.color becomes style={color: props.color}
 
   for (const tag of ALLOWED_STYLE_TAGS) {
@@ -9113,23 +9693,23 @@ const Button = props => {
 // CONCATENATED MODULE: ./content-src/asrouter/components/ConditionalWrapper/ConditionalWrapper.jsx
 // lifted from https://gist.github.com/kitze/23d82bb9eb0baabfd03a6a720b1d637f
 const ConditionalWrapper = ({
   condition,
   wrap,
   children
 }) => condition ? wrap(children) : children;
 // EXTERNAL MODULE: ./content-src/asrouter/components/RichText/RichText.jsx
-var RichText = __webpack_require__(18);
+var RichText = __webpack_require__(17);
 
 // EXTERNAL MODULE: ./content-src/asrouter/template-utils.js
-var template_utils = __webpack_require__(19);
+var template_utils = __webpack_require__(18);
 
 // EXTERNAL MODULE: ./content-src/asrouter/templates/SimpleSnippet/SimpleSnippet.schema.json
-var SimpleSnippet_schema = __webpack_require__(21);
+var SimpleSnippet_schema = __webpack_require__(20);
 
 // CONCATENATED MODULE: ./content-src/asrouter/components/SnippetBase/SnippetBase.jsx
 
 
 class SnippetBase_SnippetBase extends external_React_default.a.PureComponent {
   constructor(props) {
     super(props);
     this.onBlockClicked = this.onBlockClicked.bind(this);
@@ -9567,17 +10147,17 @@ const EOYSnippet = props => {
     ...props.content
   };
   return external_React_default.a.createElement(EOYSnippet_EOYSnippetBase, EOYSnippet_extends({}, props, {
     content: extendedContent,
     form_method: "GET"
   }));
 };
 // EXTERNAL MODULE: ./content-src/asrouter/templates/FXASignupSnippet/FXASignupSnippet.schema.json
-var FXASignupSnippet_schema = __webpack_require__(22);
+var FXASignupSnippet_schema = __webpack_require__(21);
 
 // CONCATENATED MODULE: ./content-src/asrouter/templates/SubmitFormSnippet/SubmitFormSnippet.jsx
 function SubmitFormSnippet_extends() { SubmitFormSnippet_extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return SubmitFormSnippet_extends.apply(this, arguments); }
 
 
 
 
 
@@ -9909,17 +10489,17 @@ const FXASignupSnippet = props => {
   };
   return external_React_default.a.createElement(SubmitFormSnippet_SubmitFormSnippet, FXASignupSnippet_extends({}, props, {
     content: extendedContent,
     form_action: "https://accounts.firefox.com/",
     form_method: "GET"
   }));
 };
 // EXTERNAL MODULE: ./content-src/asrouter/templates/NewsletterSnippet/NewsletterSnippet.schema.json
-var NewsletterSnippet_schema = __webpack_require__(23);
+var NewsletterSnippet_schema = __webpack_require__(22);
 
 // CONCATENATED MODULE: ./content-src/asrouter/templates/NewsletterSnippet/NewsletterSnippet.jsx
 function NewsletterSnippet_extends() { NewsletterSnippet_extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return NewsletterSnippet_extends.apply(this, arguments); }
 
 
 
 
 const NewsletterSnippet = props => {
@@ -9982,17 +10562,17 @@ function isEmailOrPhoneNumber(val, conte
     return "email";
   } else if (check_phone) {
     return "phone";
   }
 
   return "";
 }
 // EXTERNAL MODULE: ./content-src/asrouter/templates/SendToDeviceSnippet/SendToDeviceSnippet.schema.json
-var SendToDeviceSnippet_schema = __webpack_require__(24);
+var SendToDeviceSnippet_schema = __webpack_require__(23);
 
 // CONCATENATED MODULE: ./content-src/asrouter/templates/SendToDeviceSnippet/SendToDeviceSnippet.jsx
 function SendToDeviceSnippet_extends() { SendToDeviceSnippet_extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return SendToDeviceSnippet_extends.apply(this, arguments); }
 
 
 
 
 
@@ -10120,997 +10700,22 @@ const SnippetsTemplates = {
   newsletter_snippet: NewsletterSnippet,
   fxa_signup_snippet: FXASignupSnippet,
   send_to_device_snippet: SendToDeviceSnippet,
   eoy_snippet: EOYSnippet,
   simple_below_search_snippet: SimpleBelowSearchSnippet_SimpleBelowSearchSnippet
 };
 
 /***/ }),
-/* 55 */
+/* 54 */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 
-// CONCATENATED MODULE: ./node_modules/fluent/src/parser.js
-/*  eslint no-magic-numbers: [0]  */
-const MAX_PLACEABLES = 100;
-const entryIdentifierRe = /-?[a-zA-Z][a-zA-Z0-9_-]*/y;
-const identifierRe = /[a-zA-Z][a-zA-Z0-9_-]*/y;
-const functionIdentifierRe = /^[A-Z][A-Z_?-]*$/;
-/**
- * The `Parser` class is responsible for parsing FTL resources.
- *
- * It's only public method is `getResource(source)` which takes an FTL string
- * and returns a two element Array with an Object of entries generated from the
- * source as the first element and an array of SyntaxError objects as the
- * second.
- *
- * This parser is optimized for runtime performance.
- *
- * There is an equivalent of this parser in syntax/parser which is
- * generating full AST which is useful for FTL tools.
- */
-
-class RuntimeParser {
-  /**
-   * Parse FTL code into entries formattable by the MessageContext.
-   *
-   * Given a string of FTL syntax, return a map of entries that can be passed
-   * to MessageContext.format and a list of errors encountered during parsing.
-   *
-   * @param {String} string
-   * @returns {Array<Object, Array>}
-   */
-  getResource(string) {
-    this._source = string;
-    this._index = 0;
-    this._length = string.length;
-    this.entries = {};
-    const errors = [];
-    this.skipWS();
-
-    while (this._index < this._length) {
-      try {
-        this.getEntry();
-      } catch (e) {
-        if (e instanceof SyntaxError) {
-          errors.push(e);
-          this.skipToNextEntryStart();
-        } else {
-          throw e;
-        }
-      }
-
-      this.skipWS();
-    }
-
-    return [this.entries, errors];
-  }
-  /**
-   * Parse the source string from the current index as an FTL entry
-   * and add it to object's entries property.
-   *
-   * @private
-   */
-
-
-  getEntry() {
-    // The index here should either be at the beginning of the file
-    // or right after new line.
-    if (this._index !== 0 && this._source[this._index - 1] !== "\n") {
-      throw this.error(`Expected an entry to start
-        at the beginning of the file or on a new line.`);
-    }
-
-    const ch = this._source[this._index]; // We don't care about comments or sections at runtime
-
-    if (ch === "/" || ch === "#" && [" ", "#", "\n"].includes(this._source[this._index + 1])) {
-      this.skipComment();
-      return;
-    }
-
-    if (ch === "[") {
-      this.skipSection();
-      return;
-    }
-
-    this.getMessage();
-  }
-  /**
-   * Skip the section entry from the current index.
-   *
-   * @private
-   */
-
-
-  skipSection() {
-    this._index += 1;
-
-    if (this._source[this._index] !== "[") {
-      throw this.error('Expected "[[" to open a section');
-    }
-
-    this._index += 1;
-    this.skipInlineWS();
-    this.getVariantName();
-    this.skipInlineWS();
-
-    if (this._source[this._index] !== "]" || this._source[this._index + 1] !== "]") {
-      throw this.error('Expected "]]" to close a section');
-    }
-
-    this._index += 2;
-  }
-  /**
-   * Parse the source string from the current index as an FTL message
-   * and add it to the entries property on the Parser.
-   *
-   * @private
-   */
-
-
-  getMessage() {
-    const id = this.getEntryIdentifier();
-    this.skipInlineWS();
-
-    if (this._source[this._index] === "=") {
-      this._index++;
-    }
-
-    this.skipInlineWS();
-    const val = this.getPattern();
-
-    if (id.startsWith("-") && val === null) {
-      throw this.error("Expected term to have a value");
-    }
-
-    let attrs = null;
-
-    if (this._source[this._index] === " ") {
-      const lineStart = this._index;
-      this.skipInlineWS();
-
-      if (this._source[this._index] === ".") {
-        this._index = lineStart;
-        attrs = this.getAttributes();
-      }
-    }
-
-    if (attrs === null && typeof val === "string") {
-      this.entries[id] = val;
-    } else {
-      if (val === null && attrs === null) {
-        throw this.error("Expected message to have a value or attributes");
-      }
-
-      this.entries[id] = {};
-
-      if (val !== null) {
-        this.entries[id].val = val;
-      }
-
-      if (attrs !== null) {
-        this.entries[id].attrs = attrs;
-      }
-    }
-  }
-  /**
-   * Skip whitespace.
-   *
-   * @private
-   */
-
-
-  skipWS() {
-    let ch = this._source[this._index];
-
-    while (ch === " " || ch === "\n" || ch === "\t" || ch === "\r") {
-      ch = this._source[++this._index];
-    }
-  }
-  /**
-   * Skip inline whitespace (space and \t).
-   *
-   * @private
-   */
-
-
-  skipInlineWS() {
-    let ch = this._source[this._index];
-
-    while (ch === " " || ch === "\t") {
-      ch = this._source[++this._index];
-    }
-  }
-  /**
-   * Skip blank lines.
-   *
-   * @private
-   */
-
-
-  skipBlankLines() {
-    while (true) {
-      const ptr = this._index;
-      this.skipInlineWS();
-
-      if (this._source[this._index] === "\n") {
-        this._index += 1;
-      } else {
-        this._index = ptr;
-        break;
-      }
-    }
-  }
-  /**
-   * Get identifier using the provided regex.
-   *
-   * By default this will get identifiers of public messages, attributes and
-   * external arguments (without the $).
-   *
-   * @returns {String}
-   * @private
-   */
-
-
-  getIdentifier(re = identifierRe) {
-    re.lastIndex = this._index;
-    const result = re.exec(this._source);
-
-    if (result === null) {
-      this._index += 1;
-      throw this.error(`Expected an identifier [${re.toString()}]`);
-    }
-
-    this._index = re.lastIndex;
-    return result[0];
-  }
-  /**
-   * Get identifier of a Message or a Term (staring with a dash).
-   *
-   * @returns {String}
-   * @private
-   */
-
-
-  getEntryIdentifier() {
-    return this.getIdentifier(entryIdentifierRe);
-  }
-  /**
-   * Get Variant name.
-   *
-   * @returns {Object}
-   * @private
-   */
-
-
-  getVariantName() {
-    let name = "";
-    const start = this._index;
-
-    let cc = this._source.charCodeAt(this._index);
-
-    if (cc >= 97 && cc <= 122 || // a-z
-    cc >= 65 && cc <= 90 || // A-Z
-    cc === 95 || cc === 32) {
-      // _ <space>
-      cc = this._source.charCodeAt(++this._index);
-    } else {
-      throw this.error("Expected a keyword (starting with [a-zA-Z_])");
-    }
-
-    while (cc >= 97 && cc <= 122 || // a-z
-    cc >= 65 && cc <= 90 || // A-Z
-    cc >= 48 && cc <= 57 || // 0-9
-    cc === 95 || cc === 45 || cc === 32) {
-      // _- <space>
-      cc = this._source.charCodeAt(++this._index);
-    } // If we encountered the end of name, we want to test if the last
-    // collected character is a space.
-    // If it is, we will backtrack to the last non-space character because
-    // the keyword cannot end with a space character.
-
-
-    while (this._source.charCodeAt(this._index - 1) === 32) {
-      this._index--;
-    }
-
-    name += this._source.slice(start, this._index);
-    return {
-      type: "varname",
-      name
-    };
-  }
-  /**
-   * Get simple string argument enclosed in `"`.
-   *
-   * @returns {String}
-   * @private
-   */
-
-
-  getString() {
-    const start = this._index + 1;
-
-    while (++this._index < this._length) {
-      const ch = this._source[this._index];
-
-      if (ch === '"') {
-        break;
-      }
-
-      if (ch === "\n") {
-        throw this.error("Unterminated string expression");
-      }
-    }
-
-    return this._source.substring(start, this._index++);
-  }
-  /**
-   * Parses a Message pattern.
-   * Message Pattern may be a simple string or an array of strings
-   * and placeable expressions.
-   *
-   * @returns {String|Array}
-   * @private
-   */
-
-
-  getPattern() {
-    // We're going to first try to see if the pattern is simple.
-    // If it is we can just look for the end of the line and read the string.
-    //
-    // Then, if either the line contains a placeable opening `{` or the
-    // next line starts an indentation, we switch to complex pattern.
-    const start = this._index;
-
-    let eol = this._source.indexOf("\n", this._index);
-
-    if (eol === -1) {
-      eol = this._length;
-    }
-
-    const firstLineContent = start !== eol ? this._source.slice(start, eol) : null;
-
-    if (firstLineContent && firstLineContent.includes("{")) {
-      return this.getComplexPattern();
-    }
-
-    this._index = eol + 1;
-    this.skipBlankLines();
-
-    if (this._source[this._index] !== " ") {
-      // No indentation means we're done with this message. Callers should check
-      // if the return value here is null. It may be OK for messages, but not OK
-      // for terms, attributes and variants.
-      return firstLineContent;
-    }
-
-    const lineStart = this._index;
-    this.skipInlineWS();
-
-    if (this._source[this._index] === ".") {
-      // The pattern is followed by an attribute. Rewind _index to the first
-      // column of the current line as expected by getAttributes.
-      this._index = lineStart;
-      return firstLineContent;
-    }
-
-    if (firstLineContent) {
-      // It's a multiline pattern which started on the same line as the
-      // identifier. Reparse the whole pattern to make sure we get all of it.
-      this._index = start;
-    }
-
-    return this.getComplexPattern();
-  }
-  /**
-   * Parses a complex Message pattern.
-   * This function is called by getPattern when the message is multiline,
-   * or contains escape chars or placeables.
-   * It does full parsing of complex patterns.
-   *
-   * @returns {Array}
-   * @private
-   */
-
-  /* eslint-disable complexity */
-
-
-  getComplexPattern() {
-    let buffer = "";
-    const content = [];
-    let placeables = 0;
-    let ch = this._source[this._index];
-
-    while (this._index < this._length) {
-      // This block handles multi-line strings combining strings separated
-      // by new line.
-      if (ch === "\n") {
-        this._index++; // We want to capture the start and end pointers
-        // around blank lines and add them to the buffer
-        // but only if the blank lines are in the middle
-        // of the string.
-
-        const blankLinesStart = this._index;
-        this.skipBlankLines();
-        const blankLinesEnd = this._index;
-
-        if (this._source[this._index] !== " ") {
-          break;
-        }
-
-        this.skipInlineWS();
-
-        if (this._source[this._index] === "}" || this._source[this._index] === "[" || this._source[this._index] === "*" || this._source[this._index] === ".") {
-          this._index = blankLinesEnd;
-          break;
-        }
-
-        buffer += this._source.substring(blankLinesStart, blankLinesEnd);
-
-        if (buffer.length || content.length) {
-          buffer += "\n";
-        }
-
-        ch = this._source[this._index];
-        continue;
-      } else if (ch === "\\") {
-        const ch2 = this._source[this._index + 1];
-
-        if (ch2 === '"' || ch2 === "{" || ch2 === "\\") {
-          ch = ch2;
-          this._index++;
-        }
-      } else if (ch === "{") {
-        // Push the buffer to content array right before placeable
-        if (buffer.length) {
-          content.push(buffer);
-        }
-
-        if (placeables > MAX_PLACEABLES - 1) {
-          throw this.error(`Too many placeables, maximum allowed is ${MAX_PLACEABLES}`);
-        }
-
-        buffer = "";
-        content.push(this.getPlaceable());
-        this._index++;
-        ch = this._source[this._index];
-        placeables++;
-        continue;
-      }
-
-      if (ch) {
-        buffer += ch;
-      }
-
-      this._index++;
-      ch = this._source[this._index];
-    }
-
-    if (content.length === 0) {
-      return buffer.length ? buffer : null;
-    }
-
-    if (buffer.length) {
-      content.push(buffer);
-    }
-
-    return content;
-  }
-  /* eslint-enable complexity */
-
-  /**
-   * Parses a single placeable in a Message pattern and returns its
-   * expression.
-   *
-   * @returns {Object}
-   * @private
-   */
-
-
-  getPlaceable() {
-    const start = ++this._index;
-    this.skipWS();
-
-    if (this._source[this._index] === "*" || this._source[this._index] === "[" && this._source[this._index + 1] !== "]") {
-      const variants = this.getVariants();
-      return {
-        type: "sel",
-        exp: null,
-        vars: variants[0],
-        def: variants[1]
-      };
-    } // Rewind the index and only support in-line white-space now.
-
-
-    this._index = start;
-    this.skipInlineWS();
-    const selector = this.getSelectorExpression();
-    this.skipWS();
-    const ch = this._source[this._index];
-
-    if (ch === "}") {
-      if (selector.type === "attr" && selector.id.name.startsWith("-")) {
-        throw this.error("Attributes of private messages cannot be interpolated.");
-      }
-
-      return selector;
-    }
-
-    if (ch !== "-" || this._source[this._index + 1] !== ">") {
-      throw this.error('Expected "}" or "->"');
-    }
-
-    if (selector.type === "ref") {
-      throw this.error("Message references cannot be used as selectors.");
-    }
-
-    if (selector.type === "var") {
-      throw this.error("Variants cannot be used as selectors.");
-    }
-
-    if (selector.type === "attr" && !selector.id.name.startsWith("-")) {
-      throw this.error("Attributes of public messages cannot be used as selectors.");
-    }
-
-    this._index += 2; // ->
-
-    this.skipInlineWS();
-
-    if (this._source[this._index] !== "\n") {
-      throw this.error("Variants should be listed in a new line");
-    }
-
-    this.skipWS();
-    const variants = this.getVariants();
-
-    if (variants[0].length === 0) {
-      throw this.error("Expected members for the select expression");
-    }
-
-    return {
-      type: "sel",
-      exp: selector,
-      vars: variants[0],
-      def: variants[1]
-    };
-  }
-  /**
-   * Parses a selector expression.
-   *
-   * @returns {Object}
-   * @private
-   */
-
-
-  getSelectorExpression() {
-    const literal = this.getLiteral();
-
-    if (literal.type !== "ref") {
-      return literal;
-    }
-
-    if (this._source[this._index] === ".") {
-      this._index++;
-      const name = this.getIdentifier();
-      this._index++;
-      return {
-        type: "attr",
-        id: literal,
-        name
-      };
-    }
-
-    if (this._source[this._index] === "[") {
-      this._index++;
-      const key = this.getVariantKey();
-      this._index++;
-      return {
-        type: "var",
-        id: literal,
-        key