Skip to content

Commit

Permalink
Adding back a stripped-down explanation of constants in Next.js (high…
Browse files Browse the repository at this point in the history
…light#6086)

We had a Discourse complaint about ambiguity around injecting
`CONSTANTS` into Next.js

https://highlightcorp.slack.com/archives/C02N2AZS8BV/p1689951434906759

This is a stripped-down explanation of how we get `CONSTANTS` injected
into Next.js.


![image](https://github.com/highlight/highlight/assets/878947/f32c745c-876c-4e37-b1ee-0c9a2fa26d8c)
  • Loading branch information
deltaepsilon authored Aug 1, 2023
1 parent e03c8c7 commit fc01cf3
Show file tree
Hide file tree
Showing 30 changed files with 186 additions and 111 deletions.
49 changes: 40 additions & 9 deletions docs-content/getting-started/fullstack-frameworks/next-js.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,39 @@ all-in-one.
yarn add @highlight-run/next @highlight-run/react highlight.run
```

## Environment Configuration (optional)

> This section is extra opinionated about Next.js constants. It's not for everyone. We like how `zod` and TypeScript work together to validate `process.env` inputs... but this is a suggestion. Do your own thing and replace our imports (`import CONSTANTS from '@/app/constants'`) with your own!
1. Install Zod: `yarn add zod`
2. Edit `.env` to add your projectID to `NEXT_PUBLIC_HIGHLIGHT_PROJECT_ID`

```bash
# .env
NEXT_PUBLIC_HIGHLIGHT_PROJECT_ID='1jdkoe52'
```

3. Feed your environment variables into the application with a constants file. We're using `zod` for this example, because it creates a validated, typed `CONSTANTS` object that plays nicely with TypeScript.

```javascript
// src/app/constants.ts
import { z } from 'zod'

// Must assign NEXT_PUBLIC_* env vars to a variable to force Next to inline them
const publicEnv = {
NEXT_PUBLIC_HIGHLIGHT_PROJECT_ID:
process.env.NEXT_PUBLIC_HIGHLIGHT_PROJECT_ID,
}

const CONSTANTS = z
.object({
NEXT_PUBLIC_HIGHLIGHT_PROJECT_ID: z.string(),
})
.parse(publicEnv)

export default CONSTANTS
```

## Client Instrumentation

This implementation requires React 17 or greater. If you're behind on React versions, follow our [React.js docs](../3_client-sdk/1_reactjs.md)
Expand All @@ -38,7 +71,7 @@ This implementation requires React 17 or greater. If you're behind on React vers
// pages/_app.tsx
import { AppProps } from 'next/app'
import CONSTANTS from '@/app/constants'
import { HighlightInit } from '@highlight-run/next/highlight-init'
import { HighlightInit } from '@highlight-run/next/client'

export default function MyApp({ Component, pageProps }: AppProps) {
return (
Expand All @@ -50,7 +83,6 @@ export default function MyApp({ Component, pageProps }: AppProps) {
enabled: true,
recordHeadersAndBody: true
}}
backendUrl={CONSTANTS.NEXT_PUBLIC_HIGHLIGHT_BACKEND_URL}
/>

<Component {...pageProps} />
Expand All @@ -66,7 +98,7 @@ export default function MyApp({ Component, pageProps }: AppProps) {
import './globals.css'

import CONSTANTS from '@/app/constants'
import { HighlightInit } from '@highlight-run/next/highlight-init'
import { HighlightInit } from '@highlight-run/next/client'

export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
Expand All @@ -78,7 +110,6 @@ export default function RootLayout({ children }: { children: React.ReactNode })
enabled: true,
recordHeadersAndBody: true
}}
backendUrl={CONSTANTS.NEXT_PUBLIC_HIGHLIGHT_BACKEND_URL}
/>

<html lang="en">
Expand All @@ -95,7 +126,7 @@ export default function RootLayout({ children }: { children: React.ReactNode })
```javascript
// src/app/utils/highlight.config.ts:
import CONSTANTS from '@/app/constants'
import { Highlight } from '@highlight-run/next'
import { Highlight } from '@highlight-run/next/server'

export const withHighlight = Highlight({
projectID: '<YOUR_PROJECT_ID>',
Expand Down Expand Up @@ -143,7 +174,7 @@ If you use a `next.config.js` file:
```javascript
// next.config.js
const nextBuildId = require('next-build-id')
const { withHighlightConfig } = require('@highlight-run/next')
const { withHighlightConfig } = require('@highlight-run/next/server')

/** @type {import('next').NextConfig} */
const nextConfig = {
Expand All @@ -165,7 +196,7 @@ If you use a `next.config.mjs` file:
import { dirname } from 'path'
import { fileURLToPath } from 'url'
import nextBuildId from 'next-build-id'
import { withHighlightConfig } from '@highlight-run/next'
import { withHighlightConfig } from '@highlight-run/next/server'

const __filename = fileURLToPath(import.meta.url)
const __dirname = dirname(__filename)
Expand Down Expand Up @@ -193,7 +224,7 @@ export async function register() {
if (process.env.NEXT_RUNTIME === 'nodejs') {
/** Conditional import required for use with Next middleware to avoid a webpack error
* https://nextjs.org/docs/pages/building-your-application/routing/middleware */
const { registerHighlight } = await import('@highlight-run/next')
const { registerHighlight } = await import('@highlight-run/next/server')

registerHighlight({
projectID: CONSTANTS.NEXT_PUBLIC_HIGHLIGHT_PROJECT_ID,
Expand Down Expand Up @@ -236,7 +267,7 @@ Make sure to implement `nextConfig.generateBuildId` so that our source map uploa
```javascript
// next.config.js
const nextBuildId = require('next-build-id')
const { withHighlightConfig } = require('@highlight-run/next')
const { withHighlightConfig } = require('@highlight-run/next/server')

/** @type {import('next').NextConfig} */
const nextConfig = {
Expand Down
1 change: 1 addition & 0 deletions e2e/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -67,3 +67,4 @@ node_modules/

.yarn
.env.local
.cache
12 changes: 6 additions & 6 deletions e2e/nextjs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ export default CONSTANTS
```javascript
// src/app/utils/highlight.config.ts:
import CONSTANTS from '@/app/constants'
import { Highlight } from '@highlight-run/next'
import { Highlight } from '@highlight-run/next/server'

if (process.env.NODE_ENV === 'development') {
// Highlight's dev instance expects HTTPS. Disable HTTPS errors in development.
Expand Down Expand Up @@ -121,7 +121,7 @@ Next.js comes out of the box instrumented for Open Telemetry. This example Highl


1. Install `next-build-id` with `npm install next-build-id`.
2. Turn on `instrumentationHook`. We've also turned on `productionBrowserSourceMaps` because Highlight is much easier to use with sourcemaps. Notice that we're transpiling the `@highlight-run/next/highlight-init` package.
2. Turn on `instrumentationHook`. We've also turned on `productionBrowserSourceMaps` because Highlight is much easier to use with sourcemaps. Notice that we're transpiling the `@highlight-run/next/client` package.

```javascript
// next.config.js
Expand All @@ -145,7 +145,7 @@ module.exports = nextConfig
```javascript
// instrumentation.ts
import CONSTANTS from '@/app/constants'
import { registerHighlight } from '@highlight-run/next'
import { registerHighlight } from '@highlight-run/next/server'

export async function register() {
registerHighlight({
Expand All @@ -163,7 +163,7 @@ export async function register() {
// pages/_app.tsx
import { AppProps } from 'next/app'
import CONSTANTS from '@/app/constants'
import { HighlightInit } from '@highlight-run/next/highlight-init'
import { HighlightInit } from '@highlight-run/next/client'

export default function MyApp({ Component, pageProps }: AppProps) {
return (
Expand Down Expand Up @@ -191,7 +191,7 @@ export default function MyApp({ Component, pageProps }: AppProps) {
import './globals.css'

import CONSTANTS from '@/app/constants'
import { HighlightInit } from '@highlight-run/next/highlight-init'
import { HighlightInit } from '@highlight-run/next/client'

export const metadata = {
title: 'Highlight Next Demo',
Expand Down Expand Up @@ -238,7 +238,7 @@ Make sure to implement `nextConfig.generateBuildId` so that our sourcemap upload
```javascript
// next.config.js
const nextBuildId = require('next-build-id')
const { withHighlightConfig } = require('@highlight-run/next')
const { withHighlightConfig } = require('@highlight-run/next/server')

/** @type {import('next').NextConfig} */
const nextConfig = {
Expand Down
2 changes: 1 addition & 1 deletion e2e/nextjs/highlight.config.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Highlight } from '@highlight-run/next'
import { Highlight } from '@highlight-run/next/server'
import winston from 'winston'

const projectID = '1jdkoe52'
Expand Down
2 changes: 1 addition & 1 deletion e2e/nextjs/instrumentation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export async function register() {
* Avoids the following error:
* An error occurred while loading instrumentation hook: (0 , _highlight_run_next__WEBPACK_IMPORTED_MODULE_1__.registerHighlight) is not a function
*/
const { registerHighlight } = await import('@highlight-run/next')
const { registerHighlight } = await import('@highlight-run/next/server')

registerHighlight({
projectID: CONSTANTS.NEXT_PUBLIC_HIGHLIGHT_PROJECT_ID,
Expand Down
6 changes: 3 additions & 3 deletions e2e/nextjs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
"@highlight-run/next": "workspace:*",
"@highlight-run/node": "workspace:*",
"@highlight-run/react": "workspace:*",
"@next/env": "^13.4.9",
"@next/env": "^13.4.12",
"@tanstack/react-query": "^4.29.7",
"@trpc/client": "^10.26.0",
"@trpc/next": "^10.26.0",
Expand All @@ -27,10 +27,10 @@
"babylonjs": "^6.11.2",
"classnames": "^2.3.2",
"eslint": "8.39.0",
"eslint-config-next": "13.4.9",
"eslint-config-next": "13.4.12",
"highlight.run": "workspace:*",
"ky": "^0.33.3",
"next": "13.4.9",
"next": "13.4.12",
"next-build-id": "^3.0.0",
"react": "18.2.0",
"react-dom": "18.2.0",
Expand Down
2 changes: 1 addition & 1 deletion e2e/nextjs/pages/_app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import { AppProps } from 'next/app'
import CONSTANTS from '@/app/constants'
import { H } from 'highlight.run'
import { HighlightInit } from '@highlight-run/next/highlight-init'
import { HighlightInit } from '@highlight-run/next/client'
import { useEffect } from 'react'

export default function MyApp({ Component, pageProps }: AppProps) {
Expand Down
2 changes: 1 addition & 1 deletion e2e/nextjs/src/app/app-h-identify/page.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
'use client'

import { H } from 'highlight.run'
import { H } from '@highlight-run/next/client'
import { useEffect } from 'react'

export default function HighlightIdentify() {
Expand Down
2 changes: 1 addition & 1 deletion e2e/nextjs/src/app/components/canvas.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import {
Color3,
} from 'babylonjs'
import React, { useEffect, useRef, useState } from 'react'
import { H } from 'highlight.run'
import { H } from '@highlight-run/next/client'

export const Canvas = ({
antialias,
Expand Down
2 changes: 1 addition & 1 deletion e2e/nextjs/src/app/components/highlight-buttons.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
'use client'

import { Button } from '@/app/components/button'
import { H } from 'highlight.run'
import { H } from '@highlight-run/next/client'

export function HighlightButtons() {
return (
Expand Down
2 changes: 1 addition & 1 deletion e2e/nextjs/src/app/components/highlight-identify.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
'use client'

import { H } from 'highlight.run'
import { H } from '@highlight-run/next/client'
import { useEffect } from 'react'

export function HighlightIdentify() {
Expand Down
2 changes: 1 addition & 1 deletion e2e/nextjs/src/app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import './globals.css'

import CONSTANTS from '@/app/constants'
import { HighlightInit } from '@highlight-run/next/highlight-init'
import { HighlightInit } from '@highlight-run/next/client'

export const metadata = {
title: 'Highlight Next Demo',
Expand Down
2 changes: 1 addition & 1 deletion e2e/nextjs/src/app/utils/highlight.config.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// src/app/utils/highlight.config.ts:
import CONSTANTS from '@/app/constants'
import { Highlight } from '@highlight-run/next'
import { Highlight } from '@highlight-run/next/server'

if (process.env.NODE_ENV === 'development') {
// Highlight's dev instance expects HTTPS. Disable HTTPS errors in development.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ If you're using the original Next.js Page router, drop \`<HighlightInit />\` in
{
text: `
// src/app/layout.tsx
import { HighlightInit } from '@highlight-run/next/highlight-init'
import { HighlightInit } from '@highlight-run/next/client'
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
Expand Down
2 changes: 1 addition & 1 deletion highlight.io/highlight.config.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Highlight } from '@highlight-run/next'
import { Highlight } from '@highlight-run/next/server'

export const withHighlight = Highlight({
projectID: '4d7k1xeo',
Expand Down
2 changes: 1 addition & 1 deletion highlight.io/next.config.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
const { withAxiom } = require('next-axiom')
const { withHighlightConfig } = require('@highlight-run/next')
const { withHighlightConfig } = require('@highlight-run/next/server')
const getStaticPages = require('./scripts/get-static-pages')

/** @type {import('next').NextConfig} */
Expand Down
6 changes: 6 additions & 0 deletions sdk/client/src/graph/generated/operations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ export type BackendErrorObjectInput = {
log_cursor?: InputMaybe<Scalars['String']>
payload?: InputMaybe<Scalars['String']>
request_id?: InputMaybe<Scalars['String']>
service: ServiceInput
session_secure_id?: InputMaybe<Scalars['String']>
source: Scalars['String']
span_id?: InputMaybe<Scalars['String']>
Expand Down Expand Up @@ -171,6 +172,11 @@ export type ReplayEventsInput = {
events: Array<InputMaybe<ReplayEventInput>>
}

export type ServiceInput = {
name: Scalars['String']
version: Scalars['String']
}

export type Session = {
__typename?: 'Session'
id?: Maybe<Scalars['ID']>
Expand Down
6 changes: 6 additions & 0 deletions sdk/client/src/graph/generated/schemas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ export type BackendErrorObjectInput = {
log_cursor?: InputMaybe<Scalars['String']>
payload?: InputMaybe<Scalars['String']>
request_id?: InputMaybe<Scalars['String']>
service: ServiceInput
session_secure_id?: InputMaybe<Scalars['String']>
source: Scalars['String']
span_id?: InputMaybe<Scalars['String']>
Expand Down Expand Up @@ -168,6 +169,11 @@ export type ReplayEventsInput = {
events: Array<InputMaybe<ReplayEventInput>>
}

export type ServiceInput = {
name: Scalars['String']
version: Scalars['String']
}

export type Session = {
__typename?: 'Session'
id?: Maybe<Scalars['ID']>
Expand Down
10 changes: 9 additions & 1 deletion sdk/highlight-next/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,14 @@

### 3.1.2

### Minor Changes
### Patch Changes

- Bumping to match `@highlight-run/node`

### 3.2.0

### Minor Changes

- Adding exports for `@highlight-run/next/client` and `@highlight-run/next/server`
> We're hoping to remove `@highlight-run/next/highlight-init` and the default `@highlight-run/next` imports in favor of the new `/client` and `/server` varieties. For now we'll maintain the original imports as aliases.
- Adding `@highlight-run/node` and `highlight.run` to `peerDependencies`
2 changes: 2 additions & 0 deletions sdk/highlight-next/bin/clean-dist.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
printf '%s%s' '"use client";' "$(cat dist/next-client.js)" > dist/next-client.js
printf '%s%s' '"use client";' "$(cat dist/next-client.mjs)" > dist/next-client.mjs
2 changes: 0 additions & 2 deletions sdk/highlight-next/bin/clean-highlight-init.sh

This file was deleted.

1 change: 1 addition & 0 deletions sdk/highlight-next/client.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './dist/next-client'
2 changes: 1 addition & 1 deletion sdk/highlight-next/index.d.ts
Original file line number Diff line number Diff line change
@@ -1 +1 @@
export * from './dist/index'
export * from './dist/server'
Loading

0 comments on commit fc01cf3

Please sign in to comment.