Skip to content

Conversation

@alexisintech
Copy link
Member

@alexisintech alexisintech commented Sep 12, 2025

🔎 Previews:

⚠️ when #2730 is merged, update session tasks guide

Tip

Just to note that the most used SDKs in order: nextjs, react, express, expo, javascript, js backend

What changed?

  • Adds examples to support most SDKs. Remix is no longer supported so removes those examples. Go and Ruby have small userbases, so skips adding those.
  • Ensures links to /backend-api have {{ target: '_blank' }} following them

FIXES DOCS-11112

Checklist

  • I have clicked on "Files changed" and performed a thorough self-review
  • All existing checks pass

@alexisintech alexisintech changed the title (WIP) Add SDK specificity across the docs Add SDK-specificity to Authentication flows, User management, and Session management sections Oct 27, 2025
@alexisintech alexisintech marked this pull request as ready for review October 27, 2025 22:50
@alexisintech alexisintech requested a review from a team as a code owner October 27, 2025 22:50
The [`getAuth()`](/docs/reference/remix/overview#get-auth) helper allows you to access the [`Auth` object](/docs/reference/backend/types/auth-object), which includes the current user's `userId` and the `isAuthenticated` property, which can be used to protect your routes.

In the following example, the `userId` is passed to the JS Backend SDK's [`getUser()`](/docs/reference/backend/user/get-user){{ target: '_blank' }} method to get the user's full `User` object. For information on how to use the JS Backend SDK, see the [JS Backend documentation](/docs/js-backend/getting-started/quickstart){{ target: '_blank' }}.
In the following example, the `userId` is passed to the JS Backend SDK's [`getUser()`](/docs/reference/backend/user/get-user) method to get the user's full `User` object. For information on how to use the JS Backend SDK, see the [reference documentation](/docs/js-backend/getting-started/quickstart).
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Question: Why do all JS Backend SDK urls use /docs/js-backend/... except for /docs/reference/backend/...? Why isn't that one /docs/reference/js-backend/...?

Copy link
Member Author

@alexisintech alexisintech Oct 29, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Question: Why do all JS Backend SDK urls use /docs/js-backend/... except for /docs/reference/backend/...? Why isn't that one /docs/reference/js-backend/...?

because the quickstart doesn't live in /reference. it lives in getting-started/
and its a doc variant (its file is quickstart.js-backend.mdx), so it has js-backend injected into the path

</Tab>
</Tabs>

### Networkless token verification
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this file be using this partial instead?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmm i'm confused what you mean. its using that partial there

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was saying, at first glance, the code here and the code in the partial looked the same. But it's not exactly. The import here is for Next.js and the partial is for backend. Plus one is using oauth_token and the otherjwtKey.

Again, it was a first glance thing. They looked the same. We can disregard.

Image

"email_address": ["[email protected]"],
"password": "my-secure-password"
}'
```
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this have the <SignedIn> + "already injected" and <SignedOut> + "replace YOUR_SECRET_KEY" callouts?


```bash {{ filename: 'terminal' }}
curl 'https://api.clerk.com/v1/users/{user_id}' -X DELETE -H 'Authorization:Bearer {{secret}}' -H 'Content-Type:application/json'
```
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this have the <SignedIn> + "already injected" and <SignedOut> + "replace YOUR_SECRET_KEY" callouts?

"birthday": "1990-01-01"
}
}' 'https://api.clerk.com/v1/users/{user_id}/metadata'
```
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this cURL:

  1. Use {{secret}} instead of CLERK_SECRET_KEY

  2. Use the <SignedIn> + "already injected" and <SignedOut> + "replace YOUR_SECRET_KEY" callouts?

```ts {{ filename: 'public.ts' }}
import { getAuth, clerkClient } from '@clerk/express'

app.post('/updateBirthday', async (req, res) => {
Copy link
Contributor

@manovotny manovotny Oct 28, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the only POST in all the examples, which begs the question:

  1. Should it be a GET for consistency
  2. Technically, wouldn't using a POST, PUT, or PATCH in all of these be a more accurate method for performing an "update" action?

export async function GET() {
const { userId } = await auth()

await clerkClient.users.deleteUser(userId)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Aren't all of these examples deleting yourself (the current logged in user)?

The previous examples were passing in a user to delete.

```
</Tab>
</Tabs>
<Include src="_partials/delete-user" />
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The previous example had a bash/cURL command, but the new partial does not.

Are we ok losing that or do we need to bring it back here or in the partial?

To create a user programmatically, you can either [make a request directly to Clerk's Backend API](/docs/reference/backend/user/create-user#backend-api-bapi-endpoint) or use the [`createUser()`](/docs/reference/backend/user/create-user) method as shown in the following example.

Use the following tabs to see examples of how to delete users using one of the following:
<Include src="_partials/create-user" />
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The previous example had a bash/cURL command, but the new partial does not.

Are we ok losing that or do we need to bring it back here or in the partial?

```ts {{ filename: 'public.ts' }}
import { getAuth, clerkClient } from '@clerk/express'

app.post('/createUser', async (req, res) => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the only POST in all the examples, which begs the question:

  1. Should it be a GET for consistency
  2. Technically, wouldn't using a POST in all of these be a more accurate method for performing an "create" action?

```ts {{ filename: 'public.ts' }}
import { getAuth, clerkClient } from '@clerk/express'

app.post('/revokeInvitation', async (req, res) => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the only POST in all the examples, which begs the question:

  1. Should it be a GET for consistency
  2. Technically, wouldn't using a POST or a DELETE in all of these be a more accurate method for performing an "revoke" action?

</Tab>

<Tab>
If you are using Remix, see the following section for how to instantiate `clerkClient`.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you want to remove Remix here?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i don't think just yet - i'm not adding more remix examples, but want to keep most support for it since its in maintenance mode

// Use `auth()` to access `isAuthenticated` and the user's ID
// The `Auth` object gives you access to properties like `isAuthenticated` and `userId`
// Accessing the `Auth` object differs depending on the SDK you're using
// https://clerk.com/docs/reference/backend/types/auth-object#how-to-access-the-auth-object
Copy link
Contributor

@manovotny manovotny Oct 28, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like the helpfulness of adding a link here, but they are going to go unchecked if/when we do updates or redirects.

Because of that, should we leave them or remove them?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

leave them because redirects will simply redirect the user to the intended page. the benefit of having them outweighs the con of a user possibly facing a redirect.


// Use the JS Backend SDK to get the user's OAuth access token
const clerkResponse = await client.users.getUserOauthAccessToken(userId, provider)
const accessToken = clerkResponse.data[0].token || ''
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The previous example was doing the same thing, but do we need to guard against data[0] here (and in all the examples below)? Will it ever not be an array? What if the userId is not found?

<If sdk="nextjs">
For `auth.protect()`, signed-out users will be redirected to the sign-in page. In the following example, `pending` users will be redirected to the sign-in page, where the `<SignIn />` component will prompt them to fulfill the session tasks. Once finished, their session will move from `pending` to an `active` (signed-in) state.
```tsx {{ filename: 'middleware.ts', mark: [[6, 8]] }}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this need to be proxy.ts now? If true, do we need to update Middleware references to Proxy in this file too?

<Tab>
If you are using the [JS Backend SDK](/docs/js-backend/getting-started/quickstart) on its own, you need to provide the `secretKey` and `publishableKey` to `createClerkClient()` so that it is passed to `authenticateRequest()`. You can set these values as [environment variables](/docs/guides/development/clerk-environment-variables#clerk-publishable-and-secret-keys) and then pass them to the function.

<Include src="_partials/authenticate-req" />
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is just this one in a partial and not the rest?

## Create an invitation

You can create an invitation in the [Clerk Dashboard](#using-clerk-dashboard) or [using the Backend API](#using-backend-api).
You can create an invitation either in the [Clerk Dashboard](#in-the-clerk-dashboard) or [programmatically](#programmatically). When making this decision, keep in mind that if you create an invitation through the Clerk Dashboard, you can only set an invitation expiration date. If you create an invitation programatically, you are able to set more options, such as the URL you want the user to be redirected to after they accept the invitation, metadata to add to the invitation, or whether an invitation should be created if there is already an existing invitation for the given email address.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I understand that we're documenting how it currently works, but this feels like we should push to have these capabilities available via the dashboard too.

@SarahSoutoul SarahSoutoul requested review from a team, NWylynko and SarahSoutoul October 29, 2025 18:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants