Skip to content

Commit

Permalink
Merge branch 'canary' into chore/update-create-next-app-when-using-ta…
Browse files Browse the repository at this point in the history
…ilwind
  • Loading branch information
Dannymx committed Jan 25, 2024
2 parents 91ab750 + 68dd495 commit 369b12d
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 63 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,10 @@ This documentation uses terms like _Span_, _Trace_ or _Exporter_ throughout this
Next.js supports OpenTelemetry instrumentation out of the box, which means that we already instrumented Next.js itself.
When you enable OpenTelemetry we will automatically wrap all your code like `getStaticProps` in _spans_ with helpful attributes.

> **Good to know**: We currently support OpenTelemetry bindings only in serverless functions.
> We don't provide any for `edge` or client side code.
## Getting Started

OpenTelemetry is extensible but setting it up properly can be quite verbose.
That's why we prepared a package `@vercel/otel` that helps you get started quickly.
It's not extensible and you should configure OpenTelemetry manually if you need to customize your setup.

### Using `@vercel/otel`

Expand All @@ -53,18 +49,20 @@ Next, create a custom [`instrumentation.ts`](/docs/pages/building-your-applicati
import { registerOTel } from '@vercel/otel'

export function register() {
registerOTel('next-app')
registerOTel({ serviceName: 'next-app' })
}
```

```js filename="your-project/instrumentation.js" switcher
import { registerOTel } from '@vercel/otel'

export function register() {
registerOTel('next-app')
registerOTel({ serviceName: 'next-app' })
}
```

See the [`@vercel/otel` documentation](https://www.npmjs.com/package/@vercel/otel) for additional configuration options.

<AppOnly>

> **Good to know**
Expand All @@ -87,7 +85,7 @@ export function register() {

### Manual OpenTelemetry configuration

If our wrapper `@vercel/otel` doesn't suit your needs, you can configure OpenTelemetry manually.
The `@vercel/otel` package provides many configuration options and should serve most of common use cases. But if it doesn't suit your needs, you can configure OpenTelemetry manually.

Firstly you need to install OpenTelemetry packages:

Expand Down Expand Up @@ -146,8 +144,7 @@ const sdk = new NodeSDK({
sdk.start()
```

Doing this is equivalent to using `@vercel/otel`, but it's possible to modify and extend.
For example, you could use `@opentelemetry/exporter-trace-otlp-grpc` instead of `@opentelemetry/exporter-trace-otlp-http` or you can specify more resource attributes.
Doing this is equivalent to using `@vercel/otel`, but it's possible to modify and extend some features that are not exposed by the `@vercel/otel`.

## Testing your instrumentation

Expand Down Expand Up @@ -183,8 +180,7 @@ Once you have your collector up and running, you can deploy your Next.js app to

### Custom Exporters

We recommend using OpenTelemetry Collector.
If that is not possible on your platform, you can use a custom OpenTelemetry exporter with [manual OpenTelemetry configuration](/docs/pages/building-your-application/optimizing/open-telemetry#manual-opentelemetry-configuration)
OpenTelemetry Collector is not necessary. You can use a custom OpenTelemetry exporter with [`@vercel/otel`](#using-vercelotel) or [manual OpenTelemetry configuration](/docs/pages/building-your-application/optimizing/open-telemetry#manual-opentelemetry-configuration).

## Custom Spans

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -164,32 +164,18 @@ export default async function handler(req, res) {
<AppOnly>

1. The user submits their credentials through a login form.
2. The form calls an API Route.
2. The form calls a Server Action.
3. Upon successful verification, the process is completed, indicating the user's successful authentication.
4. If verification is unsuccessful, an error message is shown.

Consider a login form where users can input their credentials:

```tsx filename="pages/index.tsx" switcher
import { FormEvent } from 'react'
```tsx filename="app/login/page.tsx" switcher
import { authenticate } from '@/app/lib/actions'

export default function Page() {
async function onSubmit(event: FormEvent<HTMLFormElement>) {
event.preventDefault()

const formData = new FormData(event.currentTarget)
const response = await fetch('/api/login', {
method: 'POST',
body: formData,
})

// Handle response if necessary
const data = await response.json()
// ...
}

return (
<form action={onSubmit}>
<form action={authenticate}>
<input type="email" name="email" placeholder="Email" required />
<input type="password" name="password" placeholder="Password" required />
<button type="submit">Login</button>
Expand All @@ -198,24 +184,12 @@ export default function Page() {
}
```

```jsx filename="pages/index.jsx" switcher
export default function Page() {
async function onSubmit(event) {
event.preventDefault()

const formData = new FormData(event.target)
const response = await fetch('/api/login', {
method: 'POST',
body: formData,
})

// Handle response if necessary
const data = await response.json()
// ...
}
```jsx filename="app/login/page.jsx" switcher
import { authenticate } from '@/app/lib/actions'

export default function Page() {
return (
<form action={onSubmit}>
<form action={authenticate}>
<input type="email" name="email" placeholder="Email" required />
<input type="password" name="password" placeholder="Password" required />
<button type="submit">Login</button>
Expand All @@ -224,36 +198,50 @@ export default function Page() {
}
```

The form above has two input fields for capturing the user's email and password. On submission, it calls an API Route to log in.
The form above has two input fields for capturing the user's email and password. On submission, it calls the `authenticate` Server Action.

You can then call your authentication provider's API in the API Route to handle authentication:
You can then call your Authentication Provider's API in the Server Action to handle authentication:

```ts filename="app/lib/actions.ts" switcher
'use server'

```ts filename="pages/api/login.ts" switcher
import type { NextApiRequest, NextApiResponse } from 'next'
import { signIn } from '@/auth'

export default async function handler(
req: NextApiRequest,
res: NextApiResponse
) {
export async function authenticate(formData: FormData) {
try {
await signIn('credentials', req.body)
return res.status(200).json({ success: true })
await signIn('credentials', formData)
} catch (error) {
return res.status(500).json({ error })
if (error) {
switch (error.type) {
case 'CredentialsSignin':
return 'Invalid credentials.'
default:
return 'Something went wrong.'
}
}
throw error
}
}
```

```js filename="pages/api/login.js" switcher
```js filename="app/lib/actions.js" switcher
'use server'

import { signIn } from '@/auth'

export default function handler(req, res) {
export async function authenticate(formData) {
try {
await signIn('credentials', req.body)
return res.status(200).json({ success: true })
await signIn('credentials', formData)
} catch (error) {
return res.status(500).json({ error })
if (error) {
switch (error.type) {
case 'CredentialsSignin':
return 'Invalid credentials.'
default:
return 'Something went wrong.'
}
}
throw error
}
}
```
Expand Down Expand Up @@ -861,7 +849,7 @@ Here are authentication solutions compatible with Next.js, please refer to the q
{/* TODO: Change link to authjs.dev when new documentation is ready */}
- [AuthO](https://auth0.com/docs/quickstart/webapp/nextjs/01-login)
- [Auth0](https://auth0.com/docs/quickstart/webapp/nextjs/01-login)
- [Clerk](https://clerk.com/docs/quickstarts/nextjs)
- [NextAuth.js](https://authjs.dev/guides/upgrade-to-v5)
- [Supabase](https://supabase.com/docs/guides/getting-started/quickstarts/nextjs)
Expand Down
2 changes: 1 addition & 1 deletion docs/03-pages/02-api-reference/02-functions/use-router.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ export default function Page() {
}
```

Redirecting the user to `pages/login.js`, useful for pages behind [authentication](/docs/pages/building-your-application/routing/authenticating):
Redirecting the user to `pages/login.js`, useful for pages behind [authentication](/docs/pages/building-your-application/authentication):

```jsx
import { useEffect } from 'react'
Expand Down
5 changes: 5 additions & 0 deletions packages/next/src/server/typescript/rules/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,11 @@ const API_DOCS: Record<
description: 'Next.js Metadata configurations',
link: 'https://nextjs.org/docs/app/api-reference/file-conventions/metadata',
},
maxDuration: {
description:
'`maxDuration` allows you to set max default execution time for your function. If it is not specified, the default value is dependent on your deployment platform and plan.',
link: 'https://nextjs.org/docs/app/api-reference/file-conventions/route-segment-config#maxduration',
},
}

function visitEntryConfig(
Expand Down

0 comments on commit 369b12d

Please sign in to comment.