diff --git a/apps/shared/copy/messages.ts b/apps/shared/copy/messages.ts index c947377a9..4e7d12c15 100644 --- a/apps/shared/copy/messages.ts +++ b/apps/shared/copy/messages.ts @@ -1700,6 +1700,134 @@ const messages = { native_build_streaming_desc: 'Build logs stream directly to your terminal via Server-Sent Events. See every step of your build in real-time - no waiting, no refreshing. Debug issues instantly as they happen.', native_build_view_docs: 'View Documentation', + native_build_builder_badge: 'Native iOS and Android builds from any machine', + native_build_builder_bandwidth_month: 'GiB bandwidth/month', + native_build_builder_build_hour: '{count} build hour{suffix}', + native_build_builder_build_hours: '{count} build hours{suffix}', + native_build_builder_build_minutes: '{count} build minutes{suffix}', + native_build_builder_build_minutes_zero: '0 build minutes', + native_build_builder_compare_credentials_capgo: 'Use existing local or CI secrets at build time.', + native_build_builder_compare_credentials_ci: 'Secrets must be wired into every pipeline path.', + native_build_builder_compare_credentials_feature: 'Credential handling', + native_build_builder_compare_credentials_local: 'Each build machine needs secure local signing setup.', + native_build_builder_compare_delivery_capgo: 'Build and submit from the same workflow.', + native_build_builder_compare_delivery_ci: 'Possible, but you own the automation.', + native_build_builder_compare_delivery_feature: 'Store delivery', + native_build_builder_compare_delivery_local: 'Manual export and upload steps are common.', + native_build_builder_compare_fit_capgo: 'Capacitor teams that want signed native builds without babysitting native toolchains.', + native_build_builder_compare_fit_ci: 'Teams with dedicated DevOps ownership for mobile runners.', + native_build_builder_compare_fit_feature: 'Best fit', + native_build_builder_compare_fit_local: 'Native specialists working inside Xcode or Android Studio every day.', + native_build_builder_compare_ios_capgo: 'Trigger iOS builds from macOS, Linux, Windows, or CI.', + native_build_builder_compare_ios_ci: 'Requires macOS runners and queue management.', + native_build_builder_compare_ios_feature: 'iOS from any OS', + native_build_builder_compare_ios_local: 'Requires macOS hardware for iOS output.', + native_build_builder_compare_setup_capgo: 'One CLI command after signing values are available.', + native_build_builder_compare_setup_ci: 'Maintain runners, images, certificates, and store upload scripts.', + native_build_builder_compare_setup_feature: 'First setup', + native_build_builder_compare_setup_local: 'Install Xcode, Android Studio, SDKs, Ruby, Gradle, and signing files per machine.', + native_build_builder_comparison_ci_header: 'Generic CI', + native_build_builder_comparison_eyebrow: 'Comparison', + native_build_builder_comparison_local_header: 'Local native builds', + native_build_builder_comparison_text: 'Keep the native build path simple when your team mainly ships Capacitor apps.', + native_build_builder_comparison_title: 'Capgo Builder vs. alternatives.', + native_build_builder_comparison_workflow_header: 'Workflow', + native_build_builder_credit_first: 'First {count}', + native_build_builder_credit_next: 'Next {count}', + native_build_builder_credit_over: 'Over {count}', + native_build_builder_credit_price: '{price}/min', + native_build_builder_cta_text: "Build signed iOS and Android releases from your machine or CI while keeping Capgo's existing site header, docs, and pricing flow.", + native_build_builder_cta_title: 'Native builds without the pain.', + native_build_builder_description: 'Build signed iOS and Android apps from any machine with Capgo Builder.', + native_build_builder_extra_minutes: 'Extra build minutes use prepaid credits.', + native_build_builder_faq_eyebrow: 'FAQ', + native_build_builder_faq_live_updates_a: + 'No. Use live updates for JavaScript, CSS, and asset changes that do not require store review. Use Capgo Builder when native code, plugins, permissions, icons, SDKs, or store binaries change.', + native_build_builder_faq_live_updates_q: 'Is Capgo Builder a replacement for live updates?', + native_build_builder_faq_platforms_a: 'Capgo Builder supports iOS and Android builds for Capacitor apps, including store submission workflows and downloadable signed artifacts.', + native_build_builder_faq_platforms_q: 'What platforms are supported?', + native_build_builder_faq_pricing_a: + 'Build minutes are included in paid Capgo plans, and extra minutes are available through prepaid credits. iOS uses Apple Silicon build capacity and Android uses containerized Linux builds.', + native_build_builder_faq_pricing_q: 'How does pricing work?', + native_build_builder_faq_repo_a: + 'No. The CLI uploads the build inputs from the machine or CI job where it runs. Private dependencies should already be installed before the build command starts.', + native_build_builder_faq_repo_q: 'Do you need access to my repository?', + native_build_builder_faq_signing_a: + 'You provide certificates, provisioning profiles, keystores, and store credentials through CLI flags or environment variables. Teams usually source them from their CI secret manager.', + native_build_builder_faq_signing_q: 'How does signing work?', + native_build_builder_faq_title: 'Specific answers to specific worries.', + native_build_builder_feature_artifacts_text: 'Download IPA, AAB, or APK output when you need it, while keeping the build environment disposable.', + native_build_builder_feature_artifacts_title: 'Clean build artifacts', + native_build_builder_feature_ci_text: 'Run from GitHub Actions, GitLab CI, Jenkins, local scripts, or a teammate machine. No repo access required.', + native_build_builder_feature_ci_title: 'Works in any CI', + native_build_builder_feature_logs_text: 'Stream every build step as it happens, so failures are visible where the command was started.', + native_build_builder_feature_logs_title: 'Live logs in your terminal', + native_build_builder_feature_no_setup_text: 'Build iOS on dedicated Apple Silicon and Android in isolated containers without installing Xcode or Android Studio everywhere.', + native_build_builder_feature_no_setup_title: 'Native builds without the native setup', + native_build_builder_feature_signing_text: 'Certificates, provisioning profiles, and keystores are supplied at build time from local env vars or CI secrets.', + native_build_builder_feature_signing_title: 'Bring your own signing', + native_build_builder_feature_stores_text: 'Ship signed artifacts to App Store Connect and Google Play from the same command that produced the build.', + native_build_builder_feature_stores_title: 'Upload to the stores', + native_build_builder_features_eyebrow: 'Built for shipping', + native_build_builder_features_text: 'Capgo Builder focuses on the work between a native change and a store-ready artifact.', + native_build_builder_features_title: 'No native build babysitting.', + native_build_builder_hero_subtitle: + 'One command for signed iOS and Android builds, store submission, and live build logs without maintaining native toolchains on every machine.', + native_build_builder_month_to_month: '{price}{suffix} month-to-month', + native_build_builder_monthly_active_users: 'monthly active users', + native_build_builder_no_credit_card_trial: 'No credit card required for the free trial.', + native_build_builder_one_command_eyebrow: 'One command', + native_build_builder_one_command_text: + 'Run the same build command locally or in CI. Capgo Builder handles the native build job, streams logs, signs the artifact, and can submit it after success.', + native_build_builder_one_command_title: 'Signed native builds, straight to the stores.', + native_build_builder_plan_trial: '14-day free trial', + native_build_builder_pricing_eyebrow: 'Pricing', + native_build_builder_pricing_text: 'The real Capgo plans include native build minutes. Start with a 14-day free trial, then choose monthly or annual billing.', + native_build_builder_pricing_title: "Pay for build minutes. That's it.", + native_build_builder_security_credentials_text: 'Signing material is used during the build and is not kept as stored Capgo data.', + native_build_builder_security_credentials_title: 'Credentials stay runtime-only', + native_build_builder_security_ephemeral_text: 'iOS and Android jobs run in isolated environments designed around short-lived build execution.', + native_build_builder_security_ephemeral_title: 'Ephemeral build environments', + native_build_builder_security_eyebrow: 'Security model', + native_build_builder_security_logs_text: 'Build output is delivered to the running command so teams can debug without a separate dashboard loop.', + native_build_builder_security_logs_title: 'Logs stream back to you', + native_build_builder_security_text: 'Capgo Builder is designed for teams that already treat signing material as sensitive CI data.', + native_build_builder_security_title: 'Your secrets stay your secrets.', + native_build_builder_security_upload_text: 'Capgo Builder receives the platform folder and built web assets needed for the requested native target.', + native_build_builder_security_upload_title: 'Only native build inputs upload', + native_build_builder_setup_eyebrow: 'Setup', + native_build_builder_setup_step_app: 'Point the command at your app id and target platform.', + native_build_builder_setup_step_install: 'Install the Capgo CLI in your project workflow.', + native_build_builder_setup_step_logs: 'Stream logs until the signed artifact is ready.', + native_build_builder_setup_step_signing: 'Pass signing values from your secrets manager.', + native_build_builder_setup_text: 'Add the command to a local script or CI job, pass signing values from secrets, and keep native release builds reproducible.', + native_build_builder_setup_title_prefix: 'Setup in', + native_build_builder_setup_title_time: '60 seconds', + native_build_builder_start_trial: 'Start 14-day free trial', + native_build_builder_stat_command_label: 'Local, CI, or teammate laptop', + native_build_builder_stat_command_value: '1 command', + native_build_builder_stat_credentials_label: 'Credentials kept runtime-only', + native_build_builder_stat_credentials_value: '0 stored', + native_build_builder_stat_platforms_label: 'Signed native builds', + native_build_builder_stat_platforms_value: 'iOS + Android', + native_build_builder_stat_stores_label: 'Submit after a clean build', + native_build_builder_stat_stores_value: 'Stores', + native_build_builder_storage: 'GiB storage', + native_build_builder_terminal_aria: 'Animated Capgo Builder terminal log', + native_build_builder_terminal_build: 'Building with Xcode on Apple Silicon', + native_build_builder_terminal_comment: '# Build and submit a signed iOS app', + native_build_builder_terminal_create: 'Creating build job', + native_build_builder_terminal_file: 'capgo-builder.log', + native_build_builder_terminal_install: 'Installing native dependencies', + native_build_builder_terminal_sign: 'Signing IPA from runtime credentials', + native_build_builder_terminal_submitted: 'Submitted to App Store Connect', + native_build_builder_terminal_succeeded: 'Build succeeded', + native_build_builder_terminal_upload: 'Uploading native project inputs', + native_build_builder_title: 'Capgo Builder', + native_build_builder_view_docs: 'View docs', + native_build_builder_view_pricing: 'View real pricing', + native_build_builder_yearly_billing: 'Billed annually at {amount}', + native_build_builder_yearly_billing_enterprise: 'Billed annually from {amount}', native_ios_android_functionality: 'Native iOS & Android functionality bridges. Access any device capability your app needs with clean TypeScript APIs.', native_performance_smooth_experience: 'Native performance for smooth experience', native_script_power_approximately_1_of_apps_on_google_play_store: 'Native Script power approximately $1% of apps on Google Play Store', diff --git a/apps/web/src/pages/native-build.astro b/apps/web/src/pages/native-build.astro index 621093909..a9623a609 100644 --- a/apps/web/src/pages/native-build.astro +++ b/apps/web/src/pages/native-build.astro @@ -1,20 +1,53 @@ --- import Layout from '@/layouts/Layout.astro' -import m from '@/copy/messages' +import m, { type MessageValues } from '@/copy/messages' +import { createLdJsonGraph, createServiceLdJson } from '@/lib/ldJson' +import type { Database } from '@/services/supabase.types' import { getRelativeLocaleUrl } from 'astro:i18n' -import { createServiceLdJson, createLdJsonGraph } from '@/lib/ldJson' + +type Plan = Database['public']['Tables']['plans']['Row'] + +type Credit = { + id: number + step_min: number + step_max: number + price_per_unit: number + type: string + unit_factor: number +} const locale = Astro.locals.locale const brand = Astro.locals.runtimeConfig.public.brand +const config = Astro.locals.runtimeConfig + +function copy(key: string, values: MessageValues = {}) { + return m[key](values, { locale }) +} -const title = `${brand} | ${m.native_build({}, { locale })}` -const description = m.native_build_description({}, { locale }) +const builderTitle = copy('native_build_builder_title') +const title = `${brand} | ${builderTitle}` +const description = copy('native_build_builder_description') + +let plansAll: Plan[] = [] +let credits: Credit[] = [] + +try { + const [plansResponse, creditsResponse] = await Promise.all([fetch(`${config.public.baseApiUrl}/private/plans`), fetch(`${config.public.baseApiUrl}/private/credits`)]) + + plansAll = plansResponse.ok ? await plansResponse.json() : [] + credits = creditsResponse.ok ? await creditsResponse.json() : [] +} catch (error) { + console.warn('Unable to load Capgo Builder pricing data', error) +} + +const plans = plansAll.filter((plan) => plan.name !== 'Free') +const buildCredits = credits.filter((credit) => credit.type === 'build_time').sort((a, b) => a.step_min - b.step_min) const serviceLdJson = createServiceLdJson(Astro.locals.runtimeConfig.public, { name: title, - description: description, + description, url: Astro.url.href, - serviceType: 'Software Development Service', + serviceType: 'Cloud native mobile app build service', areaServed: ['Worldwide'], }) @@ -27,598 +60,615 @@ const content = { description, ldJSON, } ---- - -
-
- -
- { - Array.from({ length: 12 }).map(() => ( -
- )) - } -
+const heroStats = [ + { value: copy('native_build_builder_stat_command_value'), label: copy('native_build_builder_stat_command_label') }, + { value: copy('native_build_builder_stat_credentials_value'), label: copy('native_build_builder_stat_credentials_label') }, + { value: copy('native_build_builder_stat_platforms_value'), label: copy('native_build_builder_stat_platforms_label') }, + { value: copy('native_build_builder_stat_stores_value'), label: copy('native_build_builder_stat_stores_label') }, +] + +const builderFeatures = [ + { + title: copy('native_build_builder_feature_no_setup_title'), + text: copy('native_build_builder_feature_no_setup_text'), + accent: 'text-emerald-300', + }, + { + title: copy('native_build_builder_feature_signing_title'), + text: copy('native_build_builder_feature_signing_text'), + accent: 'text-cyan-300', + }, + { + title: copy('native_build_builder_feature_stores_title'), + text: copy('native_build_builder_feature_stores_text'), + accent: 'text-amber-300', + }, + { + title: copy('native_build_builder_feature_ci_title'), + text: copy('native_build_builder_feature_ci_text'), + accent: 'text-sky-300', + }, + { + title: copy('native_build_builder_feature_logs_title'), + text: copy('native_build_builder_feature_logs_text'), + accent: 'text-fuchsia-300', + }, + { + title: copy('native_build_builder_feature_artifacts_title'), + text: copy('native_build_builder_feature_artifacts_text'), + accent: 'text-violet-300', + }, +] + +const setupSteps = [ + copy('native_build_builder_setup_step_install'), + copy('native_build_builder_setup_step_app'), + copy('native_build_builder_setup_step_signing'), + copy('native_build_builder_setup_step_logs'), +] + +const securityFeatures = [ + { + title: copy('native_build_builder_security_credentials_title'), + text: copy('native_build_builder_security_credentials_text'), + }, + { + title: copy('native_build_builder_security_upload_title'), + text: copy('native_build_builder_security_upload_text'), + }, + { + title: copy('native_build_builder_security_ephemeral_title'), + text: copy('native_build_builder_security_ephemeral_text'), + }, + { + title: copy('native_build_builder_security_logs_title'), + text: copy('native_build_builder_security_logs_text'), + }, +] + +const comparisons = [ + { + feature: copy('native_build_builder_compare_setup_feature'), + capgo: copy('native_build_builder_compare_setup_capgo'), + local: copy('native_build_builder_compare_setup_local'), + ci: copy('native_build_builder_compare_setup_ci'), + }, + { + feature: copy('native_build_builder_compare_ios_feature'), + capgo: copy('native_build_builder_compare_ios_capgo'), + local: copy('native_build_builder_compare_ios_local'), + ci: copy('native_build_builder_compare_ios_ci'), + }, + { + feature: copy('native_build_builder_compare_credentials_feature'), + capgo: copy('native_build_builder_compare_credentials_capgo'), + local: copy('native_build_builder_compare_credentials_local'), + ci: copy('native_build_builder_compare_credentials_ci'), + }, + { + feature: copy('native_build_builder_compare_delivery_feature'), + capgo: copy('native_build_builder_compare_delivery_capgo'), + local: copy('native_build_builder_compare_delivery_local'), + ci: copy('native_build_builder_compare_delivery_ci'), + }, + { + feature: copy('native_build_builder_compare_fit_feature'), + capgo: copy('native_build_builder_compare_fit_capgo'), + local: copy('native_build_builder_compare_fit_local'), + ci: copy('native_build_builder_compare_fit_ci'), + }, +] + +const faqs = [ + { + question: copy('native_build_builder_faq_live_updates_q'), + answer: copy('native_build_builder_faq_live_updates_a'), + }, + { + question: copy('native_build_builder_faq_repo_q'), + answer: copy('native_build_builder_faq_repo_a'), + }, + { + question: copy('native_build_builder_faq_signing_q'), + answer: copy('native_build_builder_faq_signing_a'), + }, + { + question: copy('native_build_builder_faq_pricing_q'), + answer: copy('native_build_builder_faq_pricing_a'), + }, + { + question: copy('native_build_builder_faq_platforms_q'), + answer: copy('native_build_builder_faq_platforms_a'), + }, +] + +function annualMonthlyPrice(plan: Plan) { + const price = Math.round(plan.price_y / 12) + return plan.name === 'Enterprise' ? `$${price}+` : `$${price}` +} - -
-
-
-

- - - - {m.build_from_anywhere({}, { locale })} -

-

- {m.native_build_hero_title({}, { locale })} -

-

- {m.native_build_hero_subtitle({}, { locale })} -

+function monthlyPrice(plan: Plan) { + return copy('native_build_builder_month_to_month', { price: `$${plan.price_m}`, suffix: plan.name === 'Enterprise' ? '+' : '' }) +} - - -
-
-
- - -
-
-
-

- {m.native_build_features_title({}, { locale })} -

-

- {m.native_build_features_subtitle({}, { locale })} -

-
+function yearlyBilling(plan: Plan) { + const amount = `$${formatNumber(plan.price_y)}` + return plan.name === 'Enterprise' ? copy('native_build_builder_yearly_billing_enterprise', { amount }) : copy('native_build_builder_yearly_billing', { amount }) +} -
- -
-
- - - -
-

{m.native_build_feature_cloud_builds({}, { locale })}

-

- {m.native_build_feature_cloud_builds_desc({}, { locale })} -

-
+function planDescription(plan: Plan) { + if (plan.name === 'Solo') return copy('plan_solo_desc') + if (plan.name === 'Maker') return copy('plan_maker_desc') + if (plan.name === 'Team') return copy('plan_team_desc') + if (plan.name === 'Enterprise') return copy('plan_payasyougo_desc') + return plan.market_desc ?? plan.description ?? '' +} - -
-
- - - -
-

{m.native_build_feature_auto_signing({}, { locale })}

-

- {m.native_build_feature_auto_signing_desc({}, { locale })} -

-
+function formatNumber(value: number) { + return new Intl.NumberFormat(locale).format(value) +} - -
-
- - - -
-

{m.native_build_feature_store_upload({}, { locale })}

-

- {m.native_build_feature_store_upload_desc({}, { locale })} -

-
+function buildTimeDisplay(buildTimeSeconds: number, name?: string) { + if (!buildTimeSeconds) return copy('native_build_builder_build_minutes_zero') - -
-
- - - -
-

{m.native_build_feature_ci_cd({}, { locale })}

-

- {m.native_build_feature_ci_cd_desc({}, { locale })} -

-
+ const buildTimeHours = Math.floor(buildTimeSeconds / 3600) + const buildTimeMinutes = Math.floor(buildTimeSeconds / 60) + const suffix = name === 'Enterprise' ? '+' : '' - -
-
- - - -
-

{m.native_build_feature_credentials({}, { locale })}

-

- {m.native_build_feature_credentials_desc({}, { locale })} -

-
+ if (buildTimeHours >= 1) { + return copy(buildTimeHours === 1 ? 'native_build_builder_build_hour' : 'native_build_builder_build_hours', { count: buildTimeHours, suffix }) + } - -
-
- - - -
-

{m.native_build_feature_logs({}, { locale })}

-

- {m.native_build_feature_logs_desc({}, { locale })} -

-
+ return copy('native_build_builder_build_minutes', { count: buildTimeMinutes, suffix }) +} + +function compactNumber(value: number) { + if (value >= 1000) return `${formatNumber(value / 1000).replace(/\.0$/, '')}k` + return formatNumber(value) +} + +function creditStepLabel(credit: Credit, index: number, total: number) { + const normalizedMin = credit.step_min / credit.unit_factor + const normalizedMax = credit.step_max / credit.unit_factor + + if (index === 0) return copy('native_build_builder_credit_first', { count: compactNumber(normalizedMax) }) + if (index === total - 1) return copy('native_build_builder_credit_over', { count: compactNumber(normalizedMin) }) + + return copy('native_build_builder_credit_next', { count: compactNumber(normalizedMax - normalizedMin) }) +} + +function creditPrice(credit: Credit) { + return copy('native_build_builder_credit_price', { price: `$${parseFloat(credit.price_per_unit.toFixed(4))}` }) +} +--- + + +
+
+
+
+
+

+ {copy('native_build_builder_badge')} +

+

{builderTitle}

+

+ {copy('native_build_builder_hero_subtitle')} +

+ +

{copy('native_build_builder_no_credit_card_trial')}

-
-
- -
-
-
-
-

- {m.native_build_cli_title({}, { locale })} -

-

- {m.native_build_cli_subtitle({}, { locale })} -

-
-

- {m.native_build_streaming_desc({}, { locale })} -

-
-
-
-
-
-
-
- Terminal -
-
# {m.native_build_cli_example({}, { locale })}
-npx @capgo/cli build com.example.app \
-  --platform ios \
-  --build-mode release
-
- Creating build job...
- Uploading project (15.2 MB)...
- Build started
-
-# Real-time logs stream to your terminal
- Running pod install...
- Building with Xcode...
- Signing IPA...
- Build succeeded in 7m 23s
- Submitted to App Store Connect
-
+
+ { + heroStats.map((item) => ( +
+

{item.value}

+

{item.label}

+
+ )) + }
- -
-
-
-

- {m.native_build_security_title({}, { locale })} -

-

- {m.native_build_security_subtitle({}, { locale })} +

+
+
+

{copy('native_build_builder_one_command_eyebrow')}

+

{copy('native_build_builder_one_command_title')}

+

+ {copy('native_build_builder_one_command_text')}

-
-
-
- - - +
+
+
+ + +
-

{m.native_build_security_feature1_title({}, { locale })}

-

{m.native_build_security_feature1_desc({}, { locale })}

+
{copy('native_build_builder_terminal_file')}
-
-
- - - +
+
{copy('native_build_builder_terminal_comment')}
+
+ bunx @capgo/cli build com.example.app \
-

{m.native_build_security_feature2_title({}, { locale })}

-

{m.native_build_security_feature2_desc({}, { locale })}

-
-
-
- - - +
--platform ios \
+
--build-mode release \
+
--submit
+
+
ok {copy('native_build_builder_terminal_create')}
+
ok {copy('native_build_builder_terminal_upload')}
+
run {copy('native_build_builder_terminal_install')}
+
run {copy('native_build_builder_terminal_build')}
+
run {copy('native_build_builder_terminal_sign')}
+
ok {copy('native_build_builder_terminal_succeeded')}
+
+ ok + {copy('native_build_builder_terminal_submitted')}
-

{m.native_build_security_feature3_title({}, { locale })}

-

{m.native_build_security_feature3_desc({}, { locale })}

-
-
-
- - - - + -

{m.native_build_security_feature4_title({}, { locale })}

-

{m.native_build_security_feature4_desc({}, { locale })}

- -
-
-
-
-
-
- Storage costs - $0 -
-
- Log storage - $0 -
-
- Artifact storage - $0 -
-
- You only pay - Build minutes -
-
-
-
-

- {m.native_build_pricing_title({}, { locale })} -

-

- {m.native_build_pricing_subtitle({}, { locale })} -

-

- {m.native_build_pricing_desc({}, { locale })} -

-
+
+
+
+

{copy('native_build_builder_features_eyebrow')}

+

{copy('native_build_builder_features_title')}

+

{copy('native_build_builder_features_text')}

-
-
- -
-
-
-

- {m.native_build_how_it_works_title({}, { locale })} -

-

- {m.native_build_how_it_works_subtitle({}, { locale })} -

+
+ { + builderFeatures.map((feature) => ( +
+
+ +
+

{feature.title}

+

{feature.text}

+
+ )) + }
+
+
-
- -
-
- 1 -
-

{m.native_build_step1_title({}, { locale })}

-

- {m.native_build_step1_desc({}, { locale })} +

+
+
+
+

{copy('native_build_builder_setup_eyebrow')}

+

+ {copy('native_build_builder_setup_title_prefix')} + {copy('native_build_builder_setup_title_time')}. +

+

+ {copy('native_build_builder_setup_text')}

+
+ bunx @capgo/cli build com.example.app --platform android +
- -
-
2
-

{m.native_build_step2_title({}, { locale })}

-

- {m.native_build_step2_desc({}, { locale })} -

+
+
    + { + setupSteps.map((step, index) => ( +
  1. + + {index + 1} + +

    {step}

    +
  2. + )) + } +
+
+
+
- -
-
- 3 -
-

{m.native_build_step3_title({}, { locale })}

-

- {m.native_build_step3_desc({}, { locale })} -

-
+
+
+
+

{copy('native_build_builder_security_eyebrow')}

+

{copy('native_build_builder_security_title')}

+

{copy('native_build_builder_security_text')}

+
+ +
+ { + securityFeatures.map((feature) => ( +
+
+ +
+

{feature.title}

+

{feature.text}

+
+ )) + }
- -
-
-
-

- {m.native_build_comparison_title({}, { locale })} -

-

- {m.native_build_comparison_subtitle({}, { locale })} -

+
+
+
+

{copy('native_build_builder_comparison_eyebrow')}

+

{copy('native_build_builder_comparison_title')}

+

{copy('native_build_builder_comparison_text')}

-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
+ { + comparisons.map((row) => ( +
+

{row.feature}

+
+
+
{builderTitle}
+
{row.capgo}
+
+
+
{copy('native_build_builder_comparison_local_header')}
+
{row.local}
+
+
+
{copy('native_build_builder_comparison_ci_header')}
+
{row.ci}
+
+
+
+ )) + } +
+ +
FeatureCloud BuildsLocal Builds
{m.native_build_comparison_xcode({}, { locale })}
{m.native_build_comparison_android({}, { locale })}
{m.native_build_comparison_signing({}, { locale })}
{m.native_build_comparison_parallel({}, { locale })}
+ - - - + + + + + + + { + comparisons.map((row) => ( + + + + + + + )) + }
{m.native_build_comparison_submission({}, { locale })}{copy('native_build_builder_comparison_workflow_header')}{builderTitle}{copy('native_build_builder_comparison_local_header')}{copy('native_build_builder_comparison_ci_header')}
{row.feature}{row.capgo}{row.local}{row.ci}
- -
-
-
-

- {m.native_build_faq_title({}, { locale })} -

-

- {m.native_build_faq_subtitle({}, { locale })} -

-
- -
-
- - -
-
- - -
-
- - -
-
- -
+ + +