Skip to content

Commit

Permalink
Add route support (#127)
Browse files Browse the repository at this point in the history
  • Loading branch information
tobiaslins authored Feb 16, 2024
1 parent 8b1c58f commit 5a011aa
Show file tree
Hide file tree
Showing 31 changed files with 695 additions and 99 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ runs:
using: composite
steps:
- name: Set up Node.js
uses: actions/setup-node@v3
uses: actions/setup-node@v4
with:
node-version-file: '.nvmrc'
registry-url: 'https://registry.npmjs.org'
Expand Down
2 changes: 1 addition & 1 deletion .nvmrc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
18.16.1
18.19.0
11 changes: 11 additions & 0 deletions apps/nextjs/app/blog/[slug]/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import Link from 'next/link';

export default function BlogPage({ params }: { params: { slug: string } }) {
return (
<div>
<h2>{params.slug}</h2>

<Link href="/blog">Back to blog</Link>
</div>
);
}
11 changes: 11 additions & 0 deletions apps/nextjs/app/blog/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import Link from 'next/link';

export default function Layout({ children }: { children: React.ReactNode }) {
return (
<div>
<Link href="/blog/my-first-blogpost">My first blog post</Link>
<Link href="/blog/new-feature-release">Feature just got released</Link>
<div>{children}</div>
</div>
);
}
3 changes: 3 additions & 0 deletions apps/nextjs/app/blog/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export default function Blog() {
return <div>Welcome on the blog</div>;
}
7 changes: 6 additions & 1 deletion apps/nextjs/app/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { Analytics } from '@vercel/analytics/next';

export const metadata = {
title: 'Next.js',
description: 'Generated by Next.js',
Expand All @@ -10,7 +12,10 @@ export default function RootLayout({
}) {
return (
<html lang="en">
<body>{children}</body>
<body>
<Analytics />
{children}
</body>
</html>
);
}
25 changes: 0 additions & 25 deletions apps/nextjs/components/withAnalytics.tsx

This file was deleted.

20 changes: 19 additions & 1 deletion apps/nextjs/e2e/development/beforeSend.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@ test.describe('beforeSend', () => {
page,
}) => {
const messages: string[] = [];
await useMockForProductionScript({
page,
onPageView: () => {},
debug: true,
});

page.on('console', (msg) => {
const message = msg.text();
Expand All @@ -28,6 +33,19 @@ test.describe('beforeSend', () => {

await page.waitForLoadState('networkidle');

expect(messages).toHaveLength(5);
expect(
messages.find((m) =>
m.includes('[pageview] http://localhost:3000/before-send/first')
)
).toBeDefined();
expect(
messages.find((m) =>
m.includes(
'[pageview] http://localhost:3000/before-send/second?secret=REDACTED'
)
)
).toBeDefined();

expect(messages.find((m) => m.includes('secret=vercel'))).toBeUndefined();
});
});
21 changes: 17 additions & 4 deletions apps/nextjs/e2e/development/pageview.spec.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,20 @@
import { test, expect } from '@playwright/test';
import { useMockForProductionScript } from '../utils';

test.describe('pageview', () => {
test('should track page views when navigating between pages', async ({
page,
}) => {
const messages: string[] = [];
await useMockForProductionScript({
page,
onPageView: () => {},
debug: true,
});

page.on('console', (msg) => {
const message = msg.text();

console.log(message);

if (
message.includes('[Vercel Web Analytics]') ||
message.includes('[Vercel Analytics]')
Expand All @@ -20,7 +24,7 @@ test.describe('pageview', () => {
});

await page.goto('/navigation/first');
await page.waitForTimeout(200);
await page.waitForTimeout(800);

await page.click('text=Next');

Expand All @@ -29,6 +33,15 @@ test.describe('pageview', () => {

await page.waitForTimeout(200);

expect(messages).toHaveLength(3);
expect(
messages.find((m) =>
m.includes('[pageview] http://localhost:3000/navigation/first')
)
).toBeDefined();
expect(
messages.find((m) =>
m.includes('[pageview] http://localhost:3000/navigation/second')
)
).toBeDefined();
});
});
4 changes: 2 additions & 2 deletions apps/nextjs/e2e/production/beforeSend.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ test.describe('beforeSend', () => {
payload: {
o: 'http://localhost:3000/before-send/first',
sv: expect.any(String),
sdkn: '@vercel/analytics',
sdkn: '@vercel/analytics/next',
sdkv: expect.any(String),
ts: expect.any(Number),
r: '',
Expand All @@ -42,7 +42,7 @@ test.describe('beforeSend', () => {
o: 'http://localhost:3000/before-send/second?secret=REDACTED',
ts: expect.any(Number),
sv: expect.any(String),
sdkn: '@vercel/analytics',
sdkn: '@vercel/analytics/next',
sdkv: expect.any(String),
},
},
Expand Down
130 changes: 128 additions & 2 deletions apps/nextjs/e2e/production/pageview.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,9 @@ test.describe('pageview', () => {
ts: expect.any(Number),
r: '',
sv: expect.any(String),
sdkn: '@vercel/analytics',
sdkn: '@vercel/analytics/next',
sdkv: expect.any(String),
dp: '/navigation/first',
},
},
{
Expand All @@ -42,8 +43,133 @@ test.describe('pageview', () => {
o: 'http://localhost:3000/navigation/second',
ts: expect.any(Number),
sv: expect.any(String),
sdkn: '@vercel/analytics',
sdkn: '@vercel/analytics/next',
sdkv: expect.any(String),
dp: '/navigation/second',
},
},
]);
});

test('should properly send dynamic route', async ({ page }) => {
const payloads: { page: string; payload: Object }[] = [];

await useMockForProductionScript({
page,
onPageView: (page, payload) => {
payloads.push({ page, payload });
},
});

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

await page.click('text=My first blog post');

await expect(page).toHaveURL('/blog/my-first-blogpost');
await expect(page.locator('h2')).toContainText('my-first-blogpost');

await page.waitForLoadState('networkidle');

await page.click('text=Back to blog');

await page.waitForLoadState('networkidle');
await expect(page).toHaveURL('/blog');

await page.click('text=Feature just got released');

await expect(page.locator('h2')).toContainText('new-feature-release');

expect(payloads).toEqual([
{
page: 'http://localhost:3000/blog',
payload: {
dp: '/blog',
o: 'http://localhost:3000/blog',
r: '',
sdkn: '@vercel/analytics/next',
sdkv: expect.any(String),
sv: expect.any(String),
ts: expect.any(Number),
},
},
{
page: 'http://localhost:3000/blog/my-first-blogpost',
payload: {
dp: '/blog/[slug]',
o: 'http://localhost:3000/blog/my-first-blogpost',
sdkn: '@vercel/analytics/next',
sdkv: expect.any(String),
sv: expect.any(String),
ts: expect.any(Number),
},
},
{
page: 'http://localhost:3000/blog',
payload: {
dp: '/blog',
o: 'http://localhost:3000/blog',
sdkn: '@vercel/analytics/next',
sdkv: expect.any(String),
sv: expect.any(String),
ts: expect.any(Number),
},
},
{
page: 'http://localhost:3000/blog/new-feature-release',
payload: {
dp: '/blog/[slug]',
o: 'http://localhost:3000/blog/new-feature-release',
sdkn: '@vercel/analytics/next',
sdkv: expect.any(String),
sv: expect.any(String),
ts: expect.any(Number),
},
},
]);
});

test('should send pageviews when route doesnt change but path does', async ({
page,
}) => {
const payloads: { page: string; payload: Object }[] = [];

await useMockForProductionScript({
page,
onPageView: (page, payload) => {
payloads.push({ page, payload });
},
});

await page.goto('/blog/my-first-blogpost');
await page.waitForLoadState('networkidle');

await page.click('text=Feature just got released');

await expect(page.locator('h2')).toContainText('new-feature-release');

expect(payloads).toEqual([
{
page: 'http://localhost:3000/blog/my-first-blogpost',
payload: {
dp: '/blog/[slug]',
o: 'http://localhost:3000/blog/my-first-blogpost',
sdkn: '@vercel/analytics/next',
sdkv: expect.any(String),
sv: expect.any(String),
ts: expect.any(Number),
r: '',
},
},
{
page: 'http://localhost:3000/blog/new-feature-release',
payload: {
dp: '/blog/[slug]',
o: 'http://localhost:3000/blog/new-feature-release',
sdkn: '@vercel/analytics/next',
sdkv: expect.any(String),
sv: expect.any(String),
ts: expect.any(Number),
},
},
]);
Expand Down
7 changes: 6 additions & 1 deletion apps/nextjs/e2e/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,16 @@ import { Page } from '@playwright/test';
export async function useMockForProductionScript(props: {
page: Page;
onPageView: (page: string, payload: Object) => void;
debug?: boolean;
}) {
await props.page.route('**/_vercel/insights/script.js', async (route, _) => {
return route.fulfill({
status: 301,
headers: { location: 'https://cdn.vercel-insights.com/v1/script.js' },
headers: {
location: props.debug
? 'https://cdn.vercel-insights.com/v1/script.debug.js'
: 'https://cdn.vercel-insights.com/v1/script.js',
},
});
});

Expand Down
1 change: 1 addition & 0 deletions apps/nextjs/next.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ const nextConfig = {
experimental: {
serverActions: true,
},
// reactStrictMode: false,
};

module.exports = nextConfig;
2 changes: 1 addition & 1 deletion apps/nextjs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
},
"dependencies": {
"@vercel/analytics": "workspace:*",
"next": "13.5.4",
"next": "14.1.0",
"react": "18.2.0",
"react-dom": "18.2.0"
},
Expand Down
22 changes: 22 additions & 0 deletions apps/nextjs/pages/_app.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { Analytics } from '@vercel/analytics/next';
import type { AppProps } from 'next/app';

export default function App({ Component, pageProps }: AppProps) {
return (
<>
<Analytics
beforeSend={(event) => {
const url = new URL(event.url);
if (url.searchParams.has('secret')) {
url.searchParams.set('secret', 'REDACTED');
}
return {
...event,
url: url.toString(),
};
}}
/>
<Component {...pageProps} />
</>
);
}
Loading

0 comments on commit 5a011aa

Please sign in to comment.