refactor(brand): pass 3 — manifests and metadata

apps/web/public/brand/{safe,lux,hanzo}/manifest.json hold per-brand web
app manifests; scripts/select-brand.sh copies the chosen one over
apps/web/public/safe.webmanifest at build time. MetaTags og/twitter
image and twitter:site read brand.appUrl / brand.twitterUrl. The
default webmanifest description is now brand-neutral.

apps/mobile/app.config.ts derives the product name from
EXPO_PUBLIC_BRAND_NAME (default 'Safe{Mobile}') and threads it into
the dev variant prefix and the camera-permission rationale string,
removing the only hard-coded brand strings in mobile config.
This commit is contained in:
Hanzo AI
2026-05-15 02:58:14 -07:00
parent 3be4599ea0
commit 28eb4c904e
6 changed files with 69 additions and 6 deletions
+6 -2
View File
@@ -15,7 +15,11 @@ const sslPinningDomains = {
],
}
const name = IS_DEV ? 'Dev-Safe{Mobile}' : 'Safe{Mobile}'
// Brand-aware product name. Reads EXPO_PUBLIC_BRAND_NAME at build time so
// `yarn build:lux` / `yarn build:hanzo` produce correctly-branded artifacts
// without touching this file. Defaults match upstream Safe.
const brandName = process.env.EXPO_PUBLIC_BRAND_NAME ?? 'Safe{Mobile}'
const name = IS_DEV ? `Dev-${brandName}` : brandName
const config: ExpoConfig = {
name: name,
@@ -147,7 +151,7 @@ const config: ExpoConfig = {
[
'react-native-vision-camera',
{
cameraPermissionText: 'Safe{Mobile} needs access to your Camera to scan QR Codes.',
cameraPermissionText: `${brandName} needs access to your Camera to scan QR Codes.`,
enableCodeScanner: true,
enableLocation: false,
},
+19
View File
@@ -0,0 +1,19 @@
{
"name": "Hanzo Vault",
"short_name": "Vault",
"description": "Hanzo Vault is the multi-signature smart account wallet for the Hanzo AI ecosystem.",
"icons": [
{
"src": "/brand/active/android-chrome-192x192.png",
"sizes": "192x192",
"type": "image/png"
},
{
"src": "/brand/active/android-chrome-512x512.png",
"sizes": "512x512",
"type": "image/png"
}
],
"start_url": "/",
"display": "standalone"
}
+19
View File
@@ -0,0 +1,19 @@
{
"name": "Lux Safe",
"short_name": "Safe",
"description": "Lux Safe is the multi-signature smart account wallet for the Lux Network.",
"icons": [
{
"src": "/brand/active/android-chrome-192x192.png",
"sizes": "192x192",
"type": "image/png"
},
{
"src": "/brand/active/android-chrome-512x512.png",
"sizes": "512x512",
"type": "image/png"
}
],
"start_url": "/",
"display": "standalone"
}
+19
View File
@@ -0,0 +1,19 @@
{
"name": "Safe",
"short_name": "Safe",
"description": "Safe (prev. Gnosis Safe) is the most trusted platform to manage digital assets on Ethereum and multiple EVMs. Over $40B secured.",
"icons": [
{
"src": "/favicons/android-chrome-192x192.png",
"sizes": "192x192",
"type": "image/png"
},
{
"src": "/favicons/android-chrome-512x512.png",
"sizes": "512x512",
"type": "image/png"
}
],
"start_url": "/",
"display": "standalone"
}
+1 -1
View File
@@ -1,7 +1,7 @@
{
"name": "Safe",
"short_name": "Safe",
"description": "Safe (prev. Gnosis Safe) is the most trusted platform to manage digital assets on Ethereum and multiple EVMs. Over $40B secured.",
"description": "The most trusted platform to manage digital assets on Ethereum and multiple EVMs.",
"icons": [
{
"src": "/favicons/android-chrome-192x192.png",
@@ -1,9 +1,11 @@
import { BRAND_NAME, IS_PRODUCTION, IS_BEHIND_IAP } from '@/config/constants'
import { ContentSecurityPolicy, StrictTransportSecurity } from '@/config/securityHeaders'
import { lightPalette, darkPalette } from '@safe-global/theme/palettes'
import { brand } from '@safe-global/brand'
const descriptionText = `${BRAND_NAME} is the most trusted smart account wallet on Ethereum with over $100B secured.`
const titleText = BRAND_NAME
const socialShareImage = `${brand.appUrl}/images/social-share.png`
const MetaTags = ({ prefetchUrl }: { prefetchUrl: string }) => (
<>
@@ -11,14 +13,14 @@ const MetaTags = ({ prefetchUrl }: { prefetchUrl: string }) => (
{!IS_PRODUCTION && <meta name="robots" content="noindex" />}
{/* Social sharing */}
<meta name="og:image" content="https://app.safe.global/images/social-share.png" />
<meta name="og:image" content={socialShareImage} />
<meta name="og:description" content={descriptionText} />
<meta name="og:title" content={titleText} />
<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:site" content="@safe" />
<meta name="twitter:site" content={brand.twitterUrl} />
<meta name="twitter:title" content={titleText} />
<meta name="twitter:description" content={descriptionText} />
<meta name="twitter:image" content="https://app.safe.global/images/social-share.png" />
<meta name="twitter:image" content={socialShareImage} />
{/* CSP */}
<meta httpEquiv="Content-Security-Policy" content={ContentSecurityPolicy} />