Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 10 additions & 15 deletions apps/landing/src/app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,14 @@
process.env.NODE_ENV === 'production' &&
process.env.LANDING_BUILD_MODE !== 'next'

const googleTagManagerScript = `(function(w,d,s,l,i){
if(w.location.hostname!=='devup-ui.com')return;
w[l]=w[l]||[];w[l].push({'gtm.start':new Date().getTime(),event:'gtm.js'});
var f=d.getElementsByTagName(s)[0],j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';
j.async=true;j.src='https://www.googletagmanager.com/gtm.js?id='+i+dl;
f.parentNode.insertBefore(j,f);
})(window,document,'script','dataLayer','GTM-PSRKC4QZ')`

export const metadata: Metadata = {
title: 'Devup UI',
description: 'Zero Config, Zero FOUC, Zero Runtime, CSS in JS Preprocessor',
Expand Down Expand Up @@ -115,19 +123,11 @@
<head>
{needsStaticExportRscTransport && (
<script
dangerouslySetInnerHTML={{ __html: staticExportRscTransport }}

Check warning on line 126 in apps/landing/src/app/layout.tsx

View workflow job for this annotation

GitHub Actions / publish

Using 'dangerouslySetInnerHTML' may have security implications
data-vinext-static-rsc-transport=""
/>
)}
<script
dangerouslySetInnerHTML={{
__html: `(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
})(window,document,'script','dataLayer','GTM-PSRKC4QZ')`,
}}
/>
<script dangerouslySetInnerHTML={{ __html: googleTagManagerScript }} />

Check warning on line 130 in apps/landing/src/app/layout.tsx

View workflow job for this annotation

GitHub Actions / publish

Using 'dangerouslySetInnerHTML' may have security implications
<link
as="font"
crossOrigin="anonymous"
Expand Down Expand Up @@ -164,12 +164,7 @@
})}
>
<noscript>
<iframe
height="0"
src="https://www.googletagmanager.com/ns.html?id=GTM-PSRKC4QZ"
style={{ display: 'none', visibility: 'hidden' }}
width="0"
/>
<span data-javascript-disabled="" hidden />
</noscript>
<ReactLenis options={{ duration: 1.4, allowNestedScroll: true }} root>
<AnchorScroll />
Expand Down
8 changes: 6 additions & 2 deletions e2e/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@ export async function waitForFontsReady(page: Page): Promise<void> {
// With scripting disabled, <noscript> contents are parsed into the DOM and
// browser-context promises cannot advance. The completed load event is the
// strongest available signal in those SSR-only contexts.
if ((await page.locator('noscript iframe').count()) > 0) return
if ((await page.locator('noscript [data-javascript-disabled]').count()) > 0) {
return
}

await page.evaluate(async (fontSpecs) => {
if (!document.fonts) return
Expand Down Expand Up @@ -86,7 +88,9 @@ export async function waitForFontsReady(page: Page): Promise<void> {
*/
export async function waitForStyleSettle(page: Page): Promise<void> {
await page.waitForLoadState('load')
if ((await page.locator('noscript iframe').count()) > 0) return
if ((await page.locator('noscript [data-javascript-disabled]').count()) > 0) {
return
}

await page.evaluate(async () => {
const finiteAnimations = document.getAnimations().filter((animation) => {
Expand Down
21 changes: 21 additions & 0 deletions e2e/landing-build-integrity.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,4 +105,25 @@ test.describe('Landing Page - Build Integrity', () => {
test('page title is set correctly', async ({ page }) => {
await expect(page).toHaveTitle(/Devup UI/)
})

test('Google Tag Manager is disabled outside the production hostname', async ({
page,
}) => {
const tagManagerRequests: string[] = []
page.on('request', (request) => {
if (new URL(request.url()).hostname === 'www.googletagmanager.com') {
tagManagerRequests.push(request.url())
}
})

await page.goto('/')
await page.waitForLoadState('networkidle')

expect(new URL(page.url()).hostname).toBe('localhost')
expect(tagManagerRequests).toHaveLength(0)
expect(await page.evaluate(() => 'dataLayer' in window)).toBe(false)
await expect(
page.locator('iframe[src*="googletagmanager.com"]'),
).toHaveCount(0)
})
})
2 changes: 1 addition & 1 deletion e2e/landing-zero-runtime.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ test.describe('Landing Page - Zero Runtime Validation', () => {
const nonVarProperties = properties.filter(
(p) => !p.trim().startsWith('--'),
)
// Allow some inline styles (GTM noscript iframe has display:none, etc.)
// Allow a small number of non-variable inline properties.
if (nonVarProperties.length > 3) {
suspiciousStyles.push(
`<${el.tagName.toLowerCase()}>: ${style.substring(0, 100)}`,
Expand Down
Loading