Skip to content

Commit 705a0f0

Browse files
committed
feat: support configurable deployment basepath
1 parent 68d0d13 commit 705a0f0

22 files changed

+1958
-1729
lines changed

apps/remix/.eslintrc.cjs

Lines changed: 0 additions & 4 deletions
This file was deleted.

apps/remix/.gitignore

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
node_modules
22

3+
/.cache
34
/build
4-
/public/build
55
.env
6-
.cache

apps/remix/README.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,16 @@
11
# Remix Vercel Web Analytics Test
2+
3+
## Setup
4+
5+
This application was created with the following commands:
6+
7+
- `cd apps`
8+
- `pnpx create-remix@latest remix` (answers: no git, no dependencies installation)
9+
- `cd remix`
10+
- TODO
11+
- edit package.json to add `"@vercel/analytics": "workspace:*"`
12+
- `pnpm i`
13+
14+
## Usage
15+
16+
Start it with `pnpm -F remix dev` and browse to [http://localhost:5173](http://localhost:5173)

apps/remix/app/root.tsx

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,13 @@
1-
import { cssBundleHref } from '@remix-run/css-bundle';
2-
import type { LinksFunction } from '@remix-run/node';
31
import {
42
Links,
5-
LiveReload,
63
Meta,
74
Outlet,
85
Scripts,
96
ScrollRestoration,
107
} from '@remix-run/react';
118
import { Analytics } from '@vercel/analytics/remix';
129

13-
export const links: LinksFunction = () => [
14-
...(cssBundleHref ? [{ rel: 'stylesheet', href: cssBundleHref }] : []),
15-
];
16-
17-
export default function App() {
10+
export function Layout({ children }: { children: React.ReactNode }) {
1811
return (
1912
<html lang="en">
2013
<head>
@@ -25,11 +18,14 @@ export default function App() {
2518
</head>
2619
<body>
2720
<Analytics />
28-
<Outlet />
21+
{children}
2922
<ScrollRestoration />
3023
<Scripts />
31-
<LiveReload />
3224
</body>
3325
</html>
3426
);
3527
}
28+
29+
export default function App() {
30+
return <Outlet />;
31+
}

apps/remix/app/routes/_index.tsx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
import { json } from '@vercel/remix';
2-
import { Form, Link, useActionData } from '@remix-run/react';
1+
import { Form, json, Link, useActionData } from '@remix-run/react';
32
import { track } from '@vercel/analytics/server';
43

54
export const action = async () => {

apps/remix/app/routes/blog.$slug.tsx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import { json, type LoaderFunctionArgs } from '@remix-run/node';
22
import { Link, useLoaderData } from '@remix-run/react';
3-
import { track } from '@vercel/analytics';
43

54
export const loader = async ({ params }: LoaderFunctionArgs) => {
65
return json({ slug: params.slug });
@@ -11,7 +10,7 @@ export default function BlogPage() {
1110
return (
1211
<div>
1312
<h1>Blog</h1>
14-
<p>We don't talk about {slug}</p>
13+
<p>We don&apos;t talk about {slug}</p>
1514
<br />
1615
<Link to="/">Back</Link>
1716
</div>

apps/remix/package.json

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,35 @@
11
{
22
"name": "remix",
33
"private": true,
4+
"sideEffects": false,
45
"type": "module",
56
"scripts": {
6-
"build": "remix build",
7-
"dev": "remix dev --manual",
8-
"start": "remix-serve ./build/index.js",
7+
"build": "remix vite:build",
8+
"dev": "remix vite:dev",
9+
"start": "remix-serve ./build/server/index.js",
910
"typecheck": "tsc"
1011
},
1112
"dependencies": {
12-
"@remix-run/css-bundle": "^2.5.0",
13-
"@remix-run/node": "^2.5.0",
14-
"@remix-run/react": "^2.5.0",
15-
"@remix-run/serve": "^2.5.0",
16-
"@remix-run/server-runtime": "^2.5.0",
13+
"@remix-run/node": "latest",
14+
"@remix-run/react": "latest",
15+
"@remix-run/serve": "latest",
1716
"@vercel/analytics": "workspace:*",
18-
"@vercel/remix": "2.5.0",
19-
"isbot": "^3.6.3",
17+
"isbot": "^4.1.0",
2018
"react": "^18.2.0",
2119
"react-dom": "^18.2.0"
2220
},
2321
"devDependencies": {
24-
"@remix-run/dev": "^2.5.0",
25-
"@remix-run/eslint-config": "^2.5.0",
26-
"@types/react": "^18.0.25",
27-
"@types/react-dom": "^18.0.8",
28-
"eslint": "^8.56.0",
29-
"typescript": "^5.3.3"
22+
"@remix-run/dev": "latest",
23+
"@types/react": "^18.2.20",
24+
"@types/react-dom": "^18.2.7",
25+
"autoprefixer": "^10.4.19",
26+
"postcss": "^8.4.38",
27+
"tailwindcss": "^3.4.4",
28+
"typescript": "^5.1.6",
29+
"vite": "^5.1.0",
30+
"vite-tsconfig-paths": "^4.2.1"
3031
},
3132
"engines": {
32-
"node": ">=18"
33+
"node": ">=20.0.0"
3334
}
3435
}

apps/remix/remix.config.js

Lines changed: 0 additions & 5 deletions
This file was deleted.

apps/remix/remix.env.d.ts

Lines changed: 0 additions & 2 deletions
This file was deleted.

apps/remix/tsconfig.json

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,32 @@
11
{
2-
"include": ["remix.env.d.ts", "**/*.ts", "**/*.tsx"],
2+
"include": [
3+
"**/*.ts",
4+
"**/*.tsx",
5+
"**/.server/**/*.ts",
6+
"**/.server/**/*.tsx",
7+
"**/.client/**/*.ts",
8+
"**/.client/**/*.tsx"
9+
],
310
"compilerOptions": {
4-
"lib": ["DOM", "DOM.Iterable", "ES2019"],
11+
"lib": ["DOM", "DOM.Iterable", "ES2022"],
12+
"types": ["@remix-run/node", "vite/client"],
513
"isolatedModules": true,
614
"esModuleInterop": true,
715
"jsx": "react-jsx",
16+
"module": "ESNext",
817
"moduleResolution": "Bundler",
918
"resolveJsonModule": true,
1019
"target": "ES2022",
1120
"strict": true,
1221
"allowJs": true,
22+
"skipLibCheck": true,
1323
"forceConsistentCasingInFileNames": true,
1424
"baseUrl": ".",
1525
"paths": {
1626
"~/*": ["./app/*"]
1727
},
1828

19-
// Remix takes care of building everything in `remix build`.
29+
// Vite takes care of building everything, not tsc.
2030
"noEmit": true
2131
}
2232
}

apps/remix/vite.config.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import { vitePlugin as remix } from '@remix-run/dev';
2+
import { defineConfig } from 'vite';
3+
4+
export default defineConfig({
5+
plugins: [remix()],
6+
});

packages/web/jest.setup.ts

Lines changed: 0 additions & 12 deletions
This file was deleted.

packages/web/package.json

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@vercel/analytics",
3-
"version": "1.5.0-canary.1",
3+
"version": "1.5.0-canary.2",
44
"description": "Gain real-time traffic insights with Vercel Web Analytics",
55
"keywords": [
66
"analytics",
@@ -42,7 +42,7 @@
4242
"require": "./dist/remix/index.js"
4343
},
4444
"./server": {
45-
"node": "./dist/server/index.js",
45+
"node": "./dist/server/index.mjs",
4646
"edge-light": "./dist/server/index.mjs",
4747
"import": "./dist/server/index.mjs",
4848
"require": "./dist/server/index.js",
@@ -94,7 +94,7 @@
9494
"dev": "pnpm copy-astro && tsup --watch",
9595
"lint": "eslint .",
9696
"lint-fix": "eslint . --fix",
97-
"test": "jest",
97+
"test": "vitest watch",
9898
"type-check": "tsc --noEmit"
9999
},
100100
"eslintConfig": {
@@ -109,19 +109,16 @@
109109
]
110110
},
111111
"devDependencies": {
112-
"@jest/globals": "^29.7.0",
113-
"@swc/core": "^1.8.0",
114-
"@swc/jest": "^0.2.37",
112+
"@swc/core": "^1.9.2",
115113
"@testing-library/jest-dom": "^6.6.3",
116114
"@testing-library/react": "^16.0.1",
117-
"@types/node": "^20.17.6",
115+
"@types/node": "^22.9.0",
118116
"@types/react": "^18.3.12",
119117
"@vercel/eslint-config": "workspace:0.0.0",
120-
"jest": "^29.7.0",
121-
"jest-environment-jsdom": "^29.7.0",
122118
"server-only": "^0.0.1",
123119
"svelte": "^5.1.10",
124-
"tsup": "7.1.0",
120+
"tsup": "8.3.5",
121+
"vitest": "^2.1.5",
125122
"vue": "^3.5.12",
126123
"vue-router": "^4.4.5"
127124
},

packages/web/src/generic.test.ts

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { beforeEach, describe, it, expect, jest } from '@jest/globals';
1+
import { beforeEach, describe, it, expect, vi } from 'vitest';
22
import { inject, track } from './generic';
33
import type { AllowedPropertyValues, Mode } from './types';
44

@@ -7,7 +7,10 @@ describe.each([
77
mode: 'development',
88
file: 'https://va.vercel-scripts.com/v1/script.debug.js',
99
},
10-
{ mode: 'production', file: 'http://localhost/_vercel/insights/script.js' },
10+
{
11+
mode: 'production',
12+
file: 'http://localhost:3000/_vercel/insights/script.js',
13+
},
1114
] as { mode: Mode; file: string }[])('in $mode mode', ({ mode, file }) => {
1215
describe('inject', () => {
1316
it('adds the script tag correctly', () => {
@@ -49,7 +52,7 @@ describe.each([
4952
});
5053

5154
it('should strip data for nested objects', () => {
52-
jest.spyOn(global.console, 'error').mockImplementation(() => void 0);
55+
vi.spyOn(global.console, 'error').mockImplementation(() => void 0);
5356

5457
const name = 'custom event';
5558
const data = { string: 'string', number: 1 };
@@ -59,10 +62,9 @@ describe.each([
5962
});
6063

6164
if (mode === 'development') {
62-
// eslint-disable-next-line jest/no-conditional-expect, no-console -- only in development
65+
// eslint-disable-next-line no-console -- only in development
6366
expect(console.error).toHaveBeenCalledTimes(1);
6467
} else {
65-
// eslint-disable-next-line jest/no-conditional-expect -- only in production
6668
expect(window.vaq?.[0]).toEqual(['event', { name, data }]);
6769
}
6870
});

packages/web/src/generic.ts

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,10 @@ import {
1414
isDevelopment,
1515
isProduction,
1616
computeRoute,
17+
getBasePath,
18+
getScriptSrc,
1719
} from './utils';
1820

19-
export const DEV_SCRIPT_URL =
20-
'https://va.vercel-scripts.com/v1/script.debug.js';
21-
export const PROD_SCRIPT_URL = '/_vercel/insights/script.js';
22-
23-
export const basepathVariableName = 'NEXT_PUBLIC_WEB_ANALYTICS_BASEPATH';
24-
2521
/**
2622
* Injects the Vercel Web Analytics script into the page head and starts tracking page views. Read more in our [documentation](https://vercel.com/docs/concepts/analytics/package).
2723
* @param [props] - Analytics options.
@@ -52,8 +48,7 @@ function inject(
5248
window.va?.('beforeSend', props.beforeSend);
5349
}
5450

55-
const src =
56-
props.scriptSrc || (isDevelopment() ? DEV_SCRIPT_URL : PROD_SCRIPT_URL);
51+
const src = getScriptSrc(props);
5752

5853
if (document.head.querySelector(`script[src*="${src}"]`)) return;
5954

@@ -67,10 +62,11 @@ function inject(
6762
if (props.disableAutoTrack) {
6863
script.dataset.disableAutoTrack = '1';
6964
}
65+
const basePath = getBasePath();
7066
if (props.endpoint) {
7167
script.dataset.endpoint = props.endpoint;
72-
} else if (process.env[basepathVariableName]) {
73-
script.dataset.endpoint = `/${process.env[basepathVariableName]}/_vercel/insights`;
68+
} else if (basePath) {
69+
script.dataset.endpoint = `${basePath}/insights`;
7470
}
7571
if (props.dsn) {
7672
script.dataset.dsn = props.dsn;

packages/web/src/react.test.tsx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import * as React from 'react';
2-
import { afterEach, beforeEach, describe, it, expect } from '@jest/globals';
2+
import { afterEach, beforeEach, describe, it, expect } from 'vitest';
33
import { cleanup, render } from '@testing-library/react';
44
import { Analytics, track } from './react';
55
import type { AllowedPropertyValues, AnalyticsProps, Mode } from './types';
@@ -20,7 +20,10 @@ describe('<Analytics />', () => {
2020
mode: 'development',
2121
file: 'https://va.vercel-scripts.com/v1/script.debug.js',
2222
},
23-
{ mode: 'production', file: 'http://localhost/_vercel/insights/script.js' },
23+
{
24+
mode: 'production',
25+
file: 'http://localhost:3000/_vercel/insights/script.js',
26+
},
2427
] as { mode: Mode; file: string }[])('in $mode mode', ({ mode, file }) => {
2528
it('adds the script tag correctly', () => {
2629
render(<Analytics mode={mode} />);

0 commit comments

Comments
 (0)