I have an expo project, and setting up a clerk auth. I have followed all the required code clerk gave, and now getting this error on the links. Everything looks okay to me, but I cant figure out how to solve this issue.
The Error:
Type '"/sign-in"' is not assignable to type 'Href<string | object>'.ts(2322)
Link.d.ts(55, 5): The expected type comes from property 'href' which is declared here on type 'IntrinsicAttributes & LinkProps<string | object> & { children?: ReactNode; }'
(property) LinkProps<string | object>.href: Href<string | object>
Path to route to.
app/_layout.tsx
import FontAwesome from '@expo/vector-icons/FontAwesome';
import { DarkTheme, DefaultTheme, ThemeProvider } from '@react-navigation/native';
import { useFonts } from 'expo-font';
import { Stack, Slot } from 'expo-router';
import * as SplashScreen from 'expo-splash-screen';
import { useEffect } from 'react';
import 'react-native-reanimated';
import { useColorScheme } from '@/components/useColorScheme';
import * as SecureStore from 'expo-secure-store'
import { ClerkProvider, ClerkLoaded } from '@clerk/clerk-expo'
const tokenCache = {
async getToken(key: string) {
try {
const item = await SecureStore.getItemAsync(key)
if (item) {
console.log(`${key} was used 🔐 n`)
} else {
console.log('No values stored under key: ' + key)
}
return item
} catch (error) {
console.error('SecureStore get item error: ', error)
await SecureStore.deleteItemAsync(key)
return null
}
},
async saveToken(key: string, value: string) {
try {
return SecureStore.setItemAsync(key, value)
} catch (err) {
return
}
},
}
const publishableKey = process.env.EXPO_PUBLIC_CLERK_PUBLISHABLE_KEY!
if (!publishableKey) {
throw new Error(
'Missing Publishable Key. Please set EXPO_PUBLIC_CLERK_PUBLISHABLE_KEY in your .env',
)
}
export {
// Catch any errors thrown by the Layout component.
ErrorBoundary,
} from 'expo-router';
export const unstable_settings = {
// Ensure that reloading on `/modal` keeps a back button present.
initialRouteName: '',
};
// Prevent the splash screen from auto-hiding before asset loading is complete.
SplashScreen.preventAutoHideAsync();
export default function RootLayout() {
const [loaded, error] = useFonts({
SpaceMono: require('../assets/fonts/SpaceMono-Regular.ttf'),
...FontAwesome.font,
});
// Expo Router uses Error Boundaries to catch errors in the navigation tree.
useEffect(() => {
if (error) throw error;
}, [error]);
useEffect(() => {
if (loaded) {
SplashScreen.hideAsync();
}
}, [loaded]);
if (!loaded) {
return null;
}
return <RootLayoutNav />;
}
function RootLayoutNav() {
const colorScheme = useColorScheme();
return (
<ClerkProvider tokenCache={tokenCache} publishableKey={publishableKey}>
<ClerkLoaded>
<Slot />
</ClerkLoaded>
</ClerkProvider>
);
}
app/(auth)/_layout.tsx
import { Redirect, Stack } from 'expo-router'
import { useAuth } from '@clerk/clerk-expo'
export default function AuthRoutesLayout() {
const { isSignedIn } = useAuth()
if (isSignedIn) {
return <Redirect href={'/'} />
}
return <Stack />
}
app/(home)/index.tsx
this is where the error originates the error is on the href of Link.
import { SignedIn, SignedOut, useUser } from '@clerk/clerk-expo'
import { Link } from 'expo-router'
import { Text, View } from 'react-native'
export default function Page() {
const { user } = useUser()
return (
<View>
<SignedIn>
<Text>Hello {user?.emailAddresses[0].emailAddress}</Text>
</SignedIn>
<SignedOut>
<Link href="/sign-in">
<Text>Sign In</Text>
</Link>
<Link href="/sign-up">
<Text>Sign Up</Text>
</Link>
</SignedOut>
</View>
)
}
2
Answers
My error also disappeared when I added a "." even though the docs say not to.
As a workaround solution I made a constant as follows and used that as the route path.
Specially we can use the same method even without making a constant, when we use functions like
router.navigate()
orroute.replace()