Skills Plugins MCP Prompt Model 博客 我的中心
开发编程 #react #mobile

zafer-skills

Expo React Native mobile app development with RevenueCat payments, AdMob ads, i18n localization, onboarding flow, paywall, and NativeTabs navigation

DeepseekModel 官方收录技能 质量 优秀 · 78 v1.0.0

获取

https://deepseekmodel.com/api/download.php?id=zaferayan-skills-skill-md&format=skill
下载 .skill 标准格式,含 system_prompt 与 model_config,导入任意 Agent 框架即可使用
.skill 文件中 system_prompt 字段的实际内容。
name zafer-skills description Expo React Native mobile app development with RevenueCat payments, AdMob ads, i18n localization, onboarding flow, paywall, and NativeTabs navigation Expo Mobile Application Development Guide IMPORTANT : This is a SKILL file, NOT a project. NEVER run npm/bun install in this folder. NEVER create code files here. When creating a new project, ALWAYS ask the user for the project path first or create it in a separate directory (e.g., ~/Projects/app-name ). This guide is created to provide context when working with Expo projects using Claude Code. MANDATORY REQUIREMENTS When creating a new Expo project, you MUST include ALL of the following: Required Screens (ALWAYS CREATE) src/app/onboarding.tsx - Swipe-based onboarding with fullscreen background video and gradient overlay src/app/paywall.tsx - RevenueCat paywall screen (shown after onboarding) src/app/settings.tsx - Settings screen with language, theme, notifications, and reset onboarding options Onboarding Video Implementation (REQUIRED) The onboarding screen MUST have a fullscreen background video. Use a URL, not a local file: import { useVideoPlayer, VideoView } from "expo-video" ; const VIDEO_URL = "https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4" ; const player = useVideoPlayer ( VIDEO_URL , ( player ) => { player. loop = true ; player. muted = true ; player. play (); }); // In render: < VideoView player = {player} style = {StyleSheet.absoluteFill} contentFit = "cover" nativeControls = {false} /> ; Do NOT just import expo-video without actually using the VideoView component. Required Navigation (ALWAYS USE) Use NativeTabs from expo-router/unstable-native-tabs for tab navigation - NEVER use @react-navigation/bottom-tabs or Tabs from expo-router Required Context Providers (ALWAYS WRAP) import { ThemeProvider } from "@/context/theme-context" ; import { DarkTheme , DefaultTheme , ThemeProvider as NavigationThemeProvider , } from "@react-navigation/native" ; < ThemeProvider > < OnboardingProvider > < AdsProvider > < NavigationThemeProvider value = {colorScheme === "dark" ? DarkTheme : DefaultTheme } > < Stack /> </ NavigationThemeProvider > </ AdsProvider > </ OnboardingProvider > </ ThemeProvider > ; Required Libraries (ALWAYS INSTALL) Use npx expo install to install libraries (NOT npm/yarn/bun install): npx expo install react-native-purchases react-native-google-mobile-ads expo-notifications i18next react-i18next expo-localization react-native-reanimated expo-video expo-audio expo-sqlite expo-linear-gradient Libraries: react-native-purchases (RevenueCat) react-native-google-mobile-ads (AdMob) expo-notifications i18next + react-i18next + expo-localization react-native-reanimated expo-video + expo-audio expo-sqlite (for localStorage) expo-linear-gradient (for gradient overlays) AdMob Configuration (REQUIRED in app.json) You MUST add this to app.json for AdMob to work: { "expo" : { "plugins" : [ [ "react-native-google-mobile-ads" , { "androidAppId" : "ca-app-pub-xxxxxxxxxxxxxxxx~yyyyyyyyyy" , "iosAppId" : "ca-app-pub-xxxxxxxxxxxxxxxx~yyyyyyyyyy" } ] ] } } For development/testing, use test App IDs: iOS: ca-app-pub-3940256099942544~1458002511 Android: ca-app-pub-3940256099942544~3347511713 Do NOT skip this configuration or the app will crash with GADInvalidInitializationException . Banner Ad Implementation (REQUIRED) You MUST implement banner ads in the Tab layout. Use this pattern: import { View , StyleSheet } from 'react-native' ; import { NativeTabs } from 'expo-router/unstable-native-tabs' ; import { useTranslation } from 'react-i18next' ; import { BannerAd , BannerAdSize , TestIds } from 'react-native-google-mobile-ads' ; import { useAds } from '@/context/ads-context' ; const adUnitId = __DEV__ ? TestIds . BANNER : 'ca-app-pub-xxxxxxxxxxxxxxxx/yyyyyyyyyy' ; export default function TabLayout ( ) { const { t } = useTranslation (); const { shouldShowAds } = useAds (); return ( < View style = {styles.container} > < NativeTabs > < NativeTabs.Trigger name = "index" > < NativeTabs.Trigger.Label > {t('tabs.home')} </ NativeTabs.Trigger.Label > < NativeTabs.Trigger.Icon sf = "house.fill" md = "home" /> </ NativeTabs.Trigger > < NativeTabs.Trigger name = "settings" > < NativeTabs.Trigger.Label > {t('tabs.settings')} </ NativeTabs.Trigger.Label > < NativeTabs.Trigger.Icon sf = "gear" md = "settings" /> </ NativeTabs.Trigger > </ NativeTabs > {shouldShowAds && ( < View style = {styles.adContainer} > < BannerAd unitId = {adUnitId} size = {BannerAdSize.ANCHORED_ADAPTIVE_BANNER} requestOptions = {{ requestNonPersonalizedAdsOnly: true , }} /> </ View > )} </ View > ); } const styles = StyleSheet . create ({ container : { flex : 1 , }, adContainer : { alignItems : 'center' , paddingBottom : 10 , }, }); ALWAYS use TestIds.BANNER in development Banner ad is placed below NativeTabs in the Tab layout Use useAds context to check shouldShowAds (hides for premium users) TURKISH LOCALIZATION (IMPORTANT) When writing tr.json , you MUST use correct Turkish characters: ı (lowercase dotless i) - NOT i İ (uppercase dotted I) - NOT I ü, Ü, ö, Ö, ç, Ç, ş, Ş, ğ, Ğ Example: ✅ "Ayarlar", "Giriş", "Çıkış", "Başla", "İleri", "Güncelle" ❌ "Ayarlar", "Giris", "Cikis", "Basla", "Ileri", "Guncelle" FORBIDDEN (NEVER USE) ❌ AsyncStorage - Use expo-sqlite/localStorage/install instead ❌ lineHeight style - Use padding/margin instead ❌ Tabs from expo-router - Use NativeTabs instead ❌ @react-navigation/bottom-tabs - Use NativeTabs instead ❌ expo-av - Use expo-video for video, expo-audio for audio instead ❌ expo-ads-admob - Use react-native-google-mobile-ads instead ❌ Any other ads library - ONLY use react-native-google-mobile-ads ❌ Reanimated hooks inside callbacks - Call at component top level Reanimated Usage (IMPORTANT) NEVER call useAnimatedStyle , useSharedValue , or other reanimated hooks inside callbacks, loops, or conditions. ❌ WRONG: const renderItem = ( ) => { const animatedStyle = useAnimatedStyle ( () => ({ opacity : 1 })); // ERROR! return < Animated.View style = {animatedStyle} /> ; }; ✅ CORRECT: function MyComponent ( ) { const animatedStyle = useAnimatedStyle ( () => ({ opacity : 1 })); // Top level return < Animated.View style = {animatedStyle} /> ; } For lists, create a separate component for each item: function AnimatedItem ( { item } ) { const animatedStyle = useAnimatedStyle ( () => ({ opacity : 1 })); return < Animated.View style = {animatedStyle} > {item.name} </ Animated.View > ; } // In FlatList: renderItem={ ( { item } ) => < AnimatedItem item = {item} /> } POST-CREATION CLEANUP (ALWAYS DO) After creating a new Expo project, you MUST: If using (tabs) folder, DELETE src/app/index.tsx to avoid route conflicts: rm src/app/index.tsx Check and remove lineHeight from these files: src/components/themed-text.tsx (comes with lineHeight by default - REMOVE IT) Any other component using lineHeight Search and remove all lineHeight occurrences: grep -r "lineHeight" src/ Replace with padding or margin instead. AFTER COMPLETING CODE (ALWAYS RUN) When you finish writing/modifying code, you MUST run these commands in order: npx expo install --fix npx expo prebuild --clean install --fix fixes dependency version mismatches prebuild --clean recreates ios and android folders Do NOT skip these steps. Project Creation When user asks to create an app, you MUST: FIRST ask for the bundle ID (e.g., "What is the bundle ID? Example: com.company.appname") Create the project in the CURRENT directory using: bunx create-expo -t default@next app-name Update app.json with the bundle ID: { "expo" : { "ios" : { "bundleIdentifier" : "com.company.appname" } , "android" : { "package" : "com.company.appname" } } } Then cd into the project and start implementing all required screens Do NOT ask for project path - always use current directory Technology Stack Framework : Expo, React Native Navigation : Expo Router (file-based routing), NativeTabs State Management : React Context API Translations : i18next, react-i18next Purchases : RevenueCat (react-native-purchases) Advertisements : Google AdMob (react-native-google-mobile-ads) Notifications : expo-notifications Animations : react-native-reanimated Storage : localStorage via expo-sqlite polyfill WARNING : DO NOT USE AsyncStorage! Use expo-sqlite polyfill instead. Example usage import "expo-sqlite/localStorage/install" ; globalThis. localStorage . setItem ( "key" , "value" ); console . log (globalThis. localStorage . getItem ( "key" )); // 'value' WARNING : NEVER USE lineHeight ! It causes layout issues in React Native. Use padding or margin instead. Project Structure project-root/ ├── src/ │ ├── app/ │ │ ├── _layout.tsx │ │ ├── index.tsx │ │ ├── explore.tsx │ │ ├── settings.tsx │ │ ├── paywall.tsx │ │ └── onboarding.tsx │ ├── components/ │ │ ├── ui/ │ │ ├── themed-text.tsx │ │ └── themed-view.tsx │ ├── constants/ │ │ ├── theme.ts │ │ └── [data-files].ts │ ├── context/ │ │ ├── onboarding-context.tsx │ │ └── ads-context.tsx │ ├── hooks/ │ │ ├── use-notifications.ts │ │ └── use-color-scheme.ts │ ├── lib/ │ │ ├── notifications.ts │ │ ├── purchases.ts │ │ ├── ads.ts │ │ └── i18n.ts │ └── locales/ │ ├── tr.json │ └── en.json ├── assets/ │ └── images/ ├── ios/ ├── android/ ├── app.json ├── eas.json ├── package.json └── tsconfig.json Tab Navigation (NativeTabs) Expo Router uses NativeTabs for native tab navigation: import { NativeTabs } from "expo-router/unstable-native-tabs" ; export default function TabLayout ( ) { return ( < NativeTabs > < NativeTabs.Trigger name = "index" > < NativeTabs.Trigger.Label > Home </ NativeTabs.Trigger.Label > < NativeTabs.Trigger.Icon sf = "house.fill" md = "home" /> </ NativeTabs.Trigger > < NativeTabs.Trigger name = "explore" > < NativeTabs.Trigger.Label > Explore </ NativeTabs.Trigger.Label > < NativeTabs.Trigger.Icon sf = "compass.fill" md = "explore" /> </ NativeTabs.Trigger > < NativeTabs.Trigger name = "settings" > < NativeTabs.Trigger.Label > Settings </ NativeTabs.Trigger.Label > < NativeTabs.Trigger.Icon sf = "gear" md = "settings" /> </ NativeTabs.Trigger > </ NativeTabs > ); } NativeTabs Properties sf : SF Symbols icon name (iOS) md : Material Design icon name (Android) name : Route file name Tab order follows trigger order Common Icons Purpose SF Symbol Material Icon Home house.fill home Explore compass.fill explore Settings gear settings Profile person.fill person Search magnifyingglass search Favorites heart.fill favorite Notifications bell.fill notifications Development Commands bun install bun start bun ios bun android bun lint npx expo install --fix npx expo prebuild --clean EAS Build Commands eas build --profile development --platform ios eas build --profile development --platform android eas build --profile production --platform ios eas build --profile production --platform android
Agent 识别该技能的关键词,点击任意一个即可复制。

该技能未提供触发词。

下载的 .skill 包内含以下字段。
字段 说明
format格式标识(skill/v1)
skill_id技能唯一 ID
name技能名称
version版本号
description技能描述
category所属分类(数组)
trigger_words触发词列表
tags标签列表
source来源标识
source_url来源链接(本页地址)
exported_at导出时间(每次下载生成)
system_prompt系统提示词正文
model_config模型参数:provider / model / temperature / max_tokens / top_p
examples示例
install_guide各平台导入说明(Coze / Dify / Claude / 自定义框架)
同一份技能可按不同平台格式导出。
.skill 标准格式,含 system_prompt 与 model_config,导入任意 Agent 框架即可使用 下载
.skillpro 增强格式,额外含脚本 / 工具 / 依赖 / 钩子占位 下载
.json 纯 JSON 导出,只含 system_prompt 与模型参数 下载
Coze 带 frontmatter 的 Markdown,Coze 平台导入用 下载
Dify Dify DSL,创建应用后直接导入 下载

每日精选 Skill 推荐,免费送到你邮箱

输入邮箱,每天接收一个精选 AI Agent 技能推荐。完全免费,持续更新。

验证码 --

提交后我们会发送一封确认邮件,点击邮件里的链接才会开始收信。

完全免费,取消任意时间。我们不会发送垃圾邮件。