Clerk
Blog

Back

Company


Apr 07, 2023

Back

Company


Apr 07, 2023

Changelog April 7, 2023

James Perkins

James Perkins


Expo 48 support, Improving our components, Runtime keys for Next.js...


This week, the team has been improving the DX of Clerk and introducing some important features.

Expo 48 Support

Clerk now has full support for Expo 48 with this change we introduced a brand new hook called useOAuth this hook dramatically improves the developer experience. Here are two examples of the code to handle Discord OAuth, both handle account transfers.

Before

1
import { useSignUp, useSignIn } from "@clerk/clerk-expo";
2
import React from "react";
3
import { Button, View } from "react-native";
4
5
import * as AuthSession from "expo-auth-session";
6
7
const SignInWithOAuth = () => {
8
const { isLoaded, signIn, setSession } = useSignIn();
9
const { signUp } = useSignUp();
10
if (!isLoaded) return null;
11
12
const handleSignInWithDiscordPress = async () => {
13
try {
14
const redirectUrl = AuthSession.makeRedirectUri({
15
path: "/oauth-native-callback",
16
});
17
18
await signIn.create({
19
strategy: "oauth_discord",
20
redirectUrl,
21
});
22
23
const {
24
firstFactorVerification: { externalVerificationRedirectURL },
25
} = signIn;
26
27
if (!externalVerificationRedirectURL)
28
throw "Something went wrong during the OAuth flow. Try again.";
29
30
const authResult = await AuthSession.startAsync({
31
authUrl: externalVerificationRedirectURL.toString(),
32
returnUrl: redirectUrl,
33
});
34
35
if (authResult.type !== "success") {
36
throw "Something went wrong during the OAuth flow. Try again.";
37
}
38
39
// Get the rotatingTokenNonce from the redirect URL parameters
40
const { rotating_token_nonce: rotatingTokenNonce } = authResult.params;
41
42
await signIn.reload({ rotatingTokenNonce });
43
44
const { createdSessionId } = signIn;
45
46
if (createdSessionId) {
47
// If we have a createdSessionId, then auth was successful
48
await setSession(createdSessionId);
49
} else {
50
// If we have no createdSessionId, then this is a first time sign-in, so
51
// we should process this as a signUp instead
52
// Throw if we're not in the right state for creating a new user
53
if (
54
!signUp ||
55
signIn.firstFactorVerification.status !== "transferable"
56
) {
57
throw "Something went wrong during the Sign up OAuth flow. Please ensure that all sign up requirements are met.";
58
}
59
60
console.log(
61
"Didn't have an account transferring, following through with new account sign up",
62
);
63
64
// Create user
65
await signUp.create({ transfer: true });
66
await signUp.reload({
67
rotatingTokenNonce: authResult.params.rotating_token_nonce,
68
});
69
await setSession(signUp.createdSessionId);
70
}
71
} catch (err) {
72
console.log(JSON.stringify(err, null, 2));
73
console.log("error signing in", err);
74
}
75
};
76
77
return (
78
<View className="rounded-lg border-2 border-gray-500 p-4">
79
<Button
80
title="Sign in with Discord"
81
onPress={handleSignInWithDiscordPress}
82
/>
83
</View>
84
);
85
};
86
87
export default SignInWithOAuth;


After

1
import { useOAuth } from "@clerk/clerk-expo";
2
import React from "react";
3
import { Button, View } from "react-native";
4
import { useWarmUpBrowser } from "../hooks/useWarmUpBrowser";
5
6
const SignInWithOAuth = () => {
7
useWarmUpBrowser();
8
9
const { startOAuthFlow } = useOAuth({ strategy: "oauth_discord" });
10
11
const handleSignInWithDiscordPress = React.useCallback(async () => {
12
try {
13
const { createdSessionId, signIn, signUp, setActive } =
14
await startOAuthFlow();
15
if (createdSessionId) {
16
setActive({ session: createdSessionId });
17
} else {
18
// Modify this code to use signIn or signUp to set this missing requirements you set in your dashboard.
19
throw new Error("There are unmet requirements, modifiy this else to handle them")
20
21
}
22
} catch (err) {
23
console.log(JSON.stringify(err, null, 2));
24
console.log("error signing in", err);
25
}
26
}, []);
27
28
return (
29
<View className="rounded-lg border-2 border-gray-500 p-4">
30
<Button
31
title="Sign in with Discord"
32
onPress={handleSignInWithDiscordPress}
33
/>
34
</View>
35
);
36
}
37
38
export default SignInWithOAuth;

At this point we believe that our authentication offering is better than Expo's direct offer! If you are ready to get started with Expo and Clerk, check out our documentation

Improving our components

Many of our users offer email,username and phone as a way for their users to authenticate. In the past we would have a single input for all of the options and the user would have to type in their phone number including the country code which made it difficult

We now offer a way to switch the input allow the user to see a familiar phone input.

@clerk/nextjs runtime key support

We can now support keys at runtime for users who may have multiple projects under a single monorepo or want fine grain usage of keys.

1
export default withClerkMiddleware((request: NextRequest) => {
2
// pass the secret key to getAuth
3
const { userId } = getAuth(req,{
4
secretKey: "CLERK_SECRET_KEY"
5
});
6
7
if (!userId) {
8
// redirect the users to /pages/sign-in/[[...index]].ts
9
10
const signInUrl = new URL("/sign-in", request.url);
11
signInUrl.searchParams.set("redirect_url", request.url);
12
return NextResponse.redirect(signInUrl);
13
}
14
return NextResponse.next();
15
},{
16
// pass the keys to Middleware
17
secretKey: "CLERK_SECRET_KEY",
18
});

Create your organization with a slug

The <CreateOrganization/> component now exposes the slug field for you to input the slug you want when an organization is created. It is still optional and by default will use the name of the organization.

Dutch language support

We now have support for localization in Dutch thanks to a Clerk user who translated our components.

1
import { ClerkProvider } from "@clerk/nextjs";
2
import { nlNL } from "@clerk/localizations";
3
import type { AppProps } from "next/app";
4
5
function MyApp({ Component, pageProps }: AppProps) {
6
return (
7
<ClerkProvider localization={nlNL} {...pageProps}>
8
<Component {...pageProps} />
9
</ClerkProvider>
10
);
11
}
12
13
export default MyApp;
Clerk's logo

Start now,
no strings attached

Start completely free for up to 10,000 monthly active users and up to 100 monthly active orgs. No credit card required.

Start Building

Pricing built for
businesses of all sizes.

Learn more about our transparent per-user costs to estimate how much your company could save by implementing Clerk.

View pricing
Clerk's logo

Newsletter!

The latest news and updates from Clerk, sent to your inbox.

Clerk logo

Clerk - Complete User Management

TwitterLinkedInGitHubDiscordFacebook

© 2024 Clerk Inc.


product
Components

© 2024 Clerk Inc.