In this tutorial, I’ll walk through setting up a basic e-commerce app using React Native Expo and integrating Clerk authentication for seamless login with Google.
- Setting Up Expo and Basic Project Structure First, let’s create a new React Native Expo project:
1
| npx create-expo-app my-app
|
Then, start the project:
- Installing Tailwind CSS and Configuring Tailwind CSS offers a quick way to style your app. Install it along with NativeWind:
1
2
| npm add nativewind
npm add --dev tailwindcss@3.3.2
|
Initialize Tailwind CSS:
→ Created Tailwind CSS config file: tailwind.config.js
1
2
3
4
5
6
7
8
| comunity-marketplace
├── expo
├── assets
├── Apps
├── node_modules
├ App.js
├ babel.config.js
└ tailwind.config.js
|
- tailwind.config.js add any custom folder to apply tailwind css
1
2
3
4
5
6
7
8
| /** @type {import('tailwindcss').Config} */
module.exports = {
content: ["./App.{js,jsx,ts,tsx}", "./<custom directory>/**/*.{js,jsx,ts,tsx}"],
theme: {
extend: {},
},
plugins: [],
}
|
- babel.config.js
1
2
3
4
5
6
7
8
| module.exports = function(api) {
api.cache(true);
return {
presets: ['babel-preset-expo'],
plugins: ["nativewind/babel"],
};
};
|
- install extensions
- Tailwind CSS IntelliSense
- ES7+ React/Redux/React-Native snippets
- Implementing UI Components → Start coding in App.js
1
2
3
4
5
6
7
8
9
10
11
12
| import { StatusBar } from 'expo-status-bar';
import React from 'react';
import { Text, View } from 'react-native';
export default function App() {
return (
<View className="flex-1 items-center justify-center bg-white">
<Text className="text-[40px] text-red-400">Open up Ampp.js to start working on your app!</Text>
<StatusBar style="auto" />
</View>
);
}asd
|
- Make a login UI to integrate Clerk Authentication
- Login Screen UI
1
2
3
4
| ├── assets
├── Apps
├ └── Screens
├ └── LoginScreen.jsx
|
- LoginScreen.jsx (type rnf)
1
2
3
4
5
6
7
8
9
10
| import { View, Text } from 'react-native'
import React from 'react'
export default function LoginScreen() {
return (
<View>
<Text>LoginScreen</Text>
</View>
)
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
| import { StatusBar } from 'expo-status-bar';
import React from 'react';
import { Text, View } from 'react-native';
import LoginScreen from './Apps/Screens/LoginScreen';
export default function App() {
return (
<View className="flex-1 bg-white">
<StatusBar style="auto" />
<LoginScreen />
</View>
);
}
|
1
2
3
4
| comunity-marketplace
├── assets
├ └── images
├ └── login.jpeg
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
| import { View, Text, Image, TouchableOpacity } from 'react-native'
import React from 'react'
export default function LoginScreen() {
return (
<View>
<Image source={require('./../../assets/images/login.jpeg')}
className = "w-full h-[400px] object-cover"
/>
<View className="p-8 bg-amber-100 mt-[-10px] rounded-3xl shadow-md">
<Text className="text-[30px] font-bold">Community Marketplace</Text>
<Text className="text-[18px] text-slate-500 mt-6">Buy SEll Marketplace where you can sell old item and make real money</Text>
<TouchableOpacity onPress={()=>console.log("SignIn")} className="p-4 bg-blue-500 rounded-full mt-20">
<Text className="text-white text-center text-[18px]">Get Started</Text>
</TouchableOpacity>
</View>
</View>
)
}
|
- Clerk authentication to use google authentication (clerk.com) 1) make acount on clerk.com 2) goto https://dashboard.clerk.com/ 3) create application with email and google options
4) install clerk with expo
- https://clerk.com/docs/quickstarts/expo
npm install @clerk/clerk-expo
5) Wrap in app.js and copy and paste publishablekey
- Then, Add SignedIn, SignedOut in App.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
| import { StatusBar } from 'expo-status-bar';
import React from 'react';
import { Text, View } from 'react-native';
import LoginScreen from './Apps/Screens/LoginScreen';
import { ClerkProvider, SignedIn, SignedOut } from '@clerk/clerk-expo';
export default function App() {
return (
<ClerkProvider publishableKey='pk_test_ZGFzaGluZy1idWZmYWxvLTAuY2xlcmsuYWNjb3VudHMuZGV2JA'>
<View className="flex-1 bg-white">
<StatusBar style="auto" />
<SignedIn>
<Text className="mt-10">You are signed in</Text>
</SignedIn>
<SignedOut>
<LoginScreen />
</SignedOut>
</View>
</ClerkProvider>
);
}
|
→ OAuth sign-in
- make hooks/useWarmUpBrowser.tsx file
1
2
3
4
5
6
7
8
9
10
11
| import React from "react";
import * as WebBrowser from "expo-web-browser";
export const useWarmUpBrowser = () => {
React.useEffect(() => {
void WebBrowser.warmUpAsync();
return () => {
void WebBrowser.coolDownAsync();
};
}, []);
};
|
npx expo install expo-web-browser
- add WebBrowser, OAuth, onPress event in LoginScreen.jsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
| import { View, Text, Image, TouchableOpacity } from 'react-native'
import * as WebBrowser from "expo-web-browser";
import React from 'react'
import { useWarmUpBrowser } from '../../hooks/useWamUpBrowser';
import { useOAuth } from "@clerk/clerk-expo";
WebBrowser.maybeCompleteAuthSession();
export default function LoginScreen() {
useWarmUpBrowser();
const { startOAuthFlow } = useOAuth({ strategy: "oauth_google" });
const onPress = React.useCallback(async () => {
try {
const { createdSessionId, signIn, signUp, setActive } =
await startOAuthFlow();
if (createdSessionId) {
setActive({ session: createdSessionId });
} else {
// Use signIn or signUp for next steps such as MFA
}
} catch (err) {
console.error("OAuth error", err);
}
}, []);
return (
<View>
<Image source={require('./../../assets/images/login.jpeg')}
className = "w-full h-[400px] object-cover"
/>
<View className="p-8 bg-amber-100 mt-[-10px] rounded-3xl shadow-md">
<Text className="text-[30px] font-bold">Community Marketplace</Text>
<Text className="text-[18px] text-slate-500 mt-6">Buy SEll Marketplace where you can sell old item and make real money</Text>
<TouchableOpacity onPress={onPress} className="p-4 bg-blue-500 rounded-full mt-20">
<Text className="text-white text-center text-[18px]">Get Started</Text>
</TouchableOpacity>
</View>
</View>
)
}
|
If press the Get Started and sign in the google account, then,