Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .env.sample
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,7 @@ AWS_ACCESS_KEY_ID="AWS_KEY_ID"
AWS_SECRET_ACCESS_KEY="AWS_SECRET_KEY"
AWS_S3_ENDPOINT="http://localhost:8081" # for dev
# AWS_S3_ENDPOINT="https://bucket-name.s3.bucket-region.amazonaws.com" # when using AWS

# Umami Analytics
UMAMI_HOST="http://localhost:3001" # for dev
UMAMI_WEBSITE_ID="<your-website-uuid>"
18 changes: 18 additions & 0 deletions docs/env-vars.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ Then, edit the `.dev.vars` file to set the required values as described below.
| `AWS_ACCESS_KEY_ID` | AWS access key for S3. Not used in local dev. | `ABCDEFGHIJKLMN12OPQR` |
| `AWS_SECRET_ACCESS_KEY` | AWS secret key for S3. Not used in local dev. | `ab1cD/2e/fGhIJ11kL13mN0pQrS45tu6V7w8X9yZ` |
| `AWS_S3_ENDPOINT` | The endpoint for the S3-compatible storage. | `http://localhost:8081` |
| `UMAMI_HOST` | URL of your Umami instance. | `http://localhost:3001` |
| `UMAMI_WEBSITE_ID` | Website ID from the Umami dashboard. | `xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx` |

## Detailed Configuration

Expand Down Expand Up @@ -123,6 +125,22 @@ AWS_S3_ENDPOINT="https://your-bucket-name.s3.your-region.amazonaws.com"

</details>

### Umami Analytics

Optional. If unset, the analytics script is silently skipped.
For local dev, start the Umami instance first:

```sh
cd localenv/umami && docker compose up -d
```

Then log in at `http://localhost:3001` (default credentials: `admin` / `umami`), go to Settings → Websites → Add website, and copy the **Website ID**.

```
UMAMI_HOST="http://localhost:3001"
UMAMI_WEBSITE_ID="<your-website-id>"
```

## Development vs Production

### Development Setup
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
import { SVGRefresh, SVGSpinner } from '~/assets/svg'
import { useConnectWallet } from '~/hooks/useConnectWallet'
import type { ElementErrors } from '~/lib/types'
import { useTrack } from '~/lib/umami'
import { useUIActions } from '~/stores/uiStore'
import type { WalletActions, WalletStore } from '~/stores/wallet-store'

Expand All @@ -26,6 +27,7 @@ export const ToolsWalletAddress = ({
}: Props) => {
const { connect, disconnect } = useConnectWallet(snap, walletActions)
const uiActions = useUIActions()
const track = useTrack()
const [error, setError] = useState<ElementErrors>()
const [isLoading, setIsLoading] = useState(false)
const inputRef = useRef<HTMLInputElement>(null)
Expand Down Expand Up @@ -63,6 +65,7 @@ export const ToolsWalletAddress = ({
const walletAddressInfo = await getWalletAddress(walletAddressUrl)
walletActions.setWalletAddressId(walletAddressInfo.id)
await connect()
track('wallet_connected', { wallet_address: snap.walletAddress })
} catch (error) {
setError({
fieldErrors: { walletAddress: [(error as Error).message] },
Expand Down
9 changes: 9 additions & 0 deletions frontend/app/lib/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,12 @@ export type ElementErrors = {
}

declare global {
interface Window {
umami?: {
track(eventName: string, eventData?: Record<string, unknown>): void
}
}

interface Env {
OP_KEY_ID: string
OP_PRIVATE_KEY: string
Expand All @@ -73,5 +79,8 @@ declare global {
AWS_S3_ENDPOINT: string

PUBLISHER_TOOLS_KV: KVNamespace

UMAMI_HOST: string
UMAMI_WEBSITE_ID: string
}
}
27 changes: 27 additions & 0 deletions frontend/app/lib/umami.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { createContext, useCallback, useContext } from 'react'
import type { ReactNode } from 'react'
import type { Tool } from '@shared/types'

type TrackFn = (eventName: string, eventData?: Record<string, unknown>) => void

const TrackContext = createContext<TrackFn>(() => {})

export function TrackProvider({
tool,
children,
}: {
tool: Tool
children: ReactNode
}) {
const track = useCallback(
(eventName: string, eventData?: Record<string, unknown>) => {
window.umami?.track(eventName, { tool, ...eventData })
},
[tool],
)
return <TrackContext.Provider value={track}>{children}</TrackContext.Provider>
}

export function useTrack(): TrackFn {
return useContext(TrackContext)
}
20 changes: 20 additions & 0 deletions frontend/app/root.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@ import {
Scripts,
ScrollRestoration,
useRouteError,
useLoaderData,
isRouteErrorResponse,
type LinksFunction,
type MetaFunction,
type LoaderFunctionArgs,
} from 'react-router'
import { Header, Footer } from '@/components'
import faviconSvg from '~/assets/images/favicon.svg?url'
Expand All @@ -17,14 +19,32 @@ import stylesheet from '~/tailwind.css?url'
import { XCircle } from './components/icons.js'
import { Button } from './components/index.js'

export async function loader({ context }: LoaderFunctionArgs) {
const { env } = context.cloudflare
return {
CONFIG_UMAMI_HOST: env.UMAMI_HOST || '',
CONFIG_UMAMI_WEBSITE_ID: env.UMAMI_WEBSITE_ID || '',
}
}

export default function App() {
const { CONFIG_UMAMI_HOST, CONFIG_UMAMI_WEBSITE_ID } =
useLoaderData<typeof loader>()

return (
<html lang="en">
<head>
<meta charSet="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<Meta />
<Links />
{CONFIG_UMAMI_HOST && CONFIG_UMAMI_WEBSITE_ID && (
<script
defer
src={`${CONFIG_UMAMI_HOST}/script.js`}
data-website-id={CONFIG_UMAMI_WEBSITE_ID}
/>
)}
Comment on lines +36 to +43
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: with this script injection here, do you think we should do any checks to make sure the URLs aren't malformed?

</head>
<body className="h-screen bg-interface-bg-main flex flex-col">
<UIProvider>
Expand Down
15 changes: 9 additions & 6 deletions frontend/app/routes/banner.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import {
MobileStepsIndicator,
BuilderProfileTabs,
} from '@/components'
import { SLIDE_ANIMATION } from '@shared/types'
import { SLIDE_ANIMATION, TOOL_BANNER } from '@shared/types'
import { BannerBuilder } from '~/components/banner/BannerBuilder'
import {
BannerPreview,
Expand All @@ -30,6 +30,7 @@ import { usePathTracker } from '~/hooks/usePathTracker'
import { useSaveProfile } from '~/hooks/useSaveProfile'
import { useScrollToWalletAddress } from '~/hooks/useScrollToWalletAddress'
import { useToolWallet } from '~/hooks/useToolWallet'
import { TrackProvider } from '~/lib/umami'
import {
actions,
banner,
Expand Down Expand Up @@ -157,13 +158,14 @@ export default function Banner() {

const isAnimationDisabled = profile.animation.type === SLIDE_ANIMATION.None
return (
<TrackProvider tool={TOOL_BANNER}>
<div className="bg-interface-bg-main w-full">
<div className="flex flex-col items-center pt-[60px] md:pt-3xl">
<div className="w-full max-w-[1280px] px-md">
<HeadingCore title="Banner" onBackClick={() => navigate('/')}>
The drawer banner informs visitors who don&apos;t have the Web
Monetization extension active, with a call-to-action linking to the
extension or providing details about the options available.
Monetization extension active, with a call-to-action linking to
the extension or providing details about the options available.
<br />
It also adds your wallet address for your site to be monetized.
</HeadingCore>
Expand Down Expand Up @@ -233,15 +235,15 @@ export default function Banner() {
<div
id="builder-actions"
className="xl:flex xl:items-center xl:justify-end xl:gap-sm xl:mt-lg xl:static xl:bg-transparent xl:p-0 xl:border-0 xl:backdrop-blur-none xl:flex-row
fixed bottom-0 left-0 right-0 flex flex-col gap-xs px-md sm:px-lg md:px-xl py-md bg-interface-bg-stickymenu/95 backdrop-blur-[20px] border-t border-field-border z-40"
fixed bottom-0 left-0 right-0 flex flex-col gap-xs px-md sm:px-lg md:px-xl py-md bg-interface-bg-stickymenu/95 backdrop-blur-[20px] border-t border-field-border z-40"
>
<div
id="builder-actions-inner"
className="xl:contents flex flex-col gap-xs mx-auto w-full xl:w-auto xl:p-0 xl:mx-0 xl:flex-row xl:gap-sm"
>
<ToolsSecondaryButton
className="xl:w-[150px] xl:rounded-lg
w-full min-w-0 border-0 xl:border order-last xl:order-first"
w-full min-w-0 border-0 xl:border order-last xl:order-first"
disabled={isLoading}
onClick={() => handleSave('save-success')}
>
Expand All @@ -256,7 +258,7 @@ export default function Banner() {
icon="script"
iconPosition={isLoadingScript ? 'none' : 'left'}
className="xl:w-[250px] xl:rounded-lg
w-full min-w-0 order-first xl:order-last"
w-full min-w-0 order-first xl:order-last"
disabled={isLoadingScript}
onClick={() => handleSave('script')}
>
Expand Down Expand Up @@ -293,5 +295,6 @@ export default function Banner() {
</div>
</div>
</div>
</TrackProvider>
)
}
4 changes: 4 additions & 0 deletions frontend/app/routes/offerwall.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ import {
toolActions,
toolState,
} from '~/stores/toolStore'
import { TrackProvider } from '~/lib/umami'
import { TOOL_OFFERWALL } from '@shared/types'
import { commitSession, getSession } from '~/utils/session.server'

export const meta: MetaFunction = () => {
Expand Down Expand Up @@ -142,6 +144,7 @@ export default function Offerwall() {
}

return (
<TrackProvider tool={TOOL_OFFERWALL}>
<div className="bg-interface-bg-main w-full">
<div className="flex flex-col items-center pt-[60px] md:pt-3xl">
<div className="w-full max-w-[1280px]">
Expand Down Expand Up @@ -277,5 +280,6 @@ export default function Offerwall() {
</div>
</div>
</div>
</TrackProvider>
)
}
4 changes: 4 additions & 0 deletions frontend/app/routes/widget.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ import {
widgetWallet,
widgetWalletActions,
} from '~/stores/widget-store'
import { TrackProvider } from '~/lib/umami'
import { TOOL_WIDGET } from '@shared/types'
import { commitSession, getSession } from '~/utils/session.server.js'

export const meta: MetaFunction = () => {
Expand Down Expand Up @@ -143,6 +145,7 @@ export default function Widget() {
}

return (
<TrackProvider tool={TOOL_WIDGET}>
<div className="bg-interface-bg-main w-full">
<div className="flex flex-col items-center pt-[60px] md:pt-3xl">
<div className="w-full max-w-[1280px] px-md">
Expand Down Expand Up @@ -279,5 +282,6 @@ export default function Widget() {
</div>
</div>
</div>
</TrackProvider>
)
}
28 changes: 28 additions & 0 deletions localenv/umami/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
services:
umami-db:
image: postgres:15-alpine
environment:
POSTGRES_DB: umami
POSTGRES_USER: umami
POSTGRES_PASSWORD: umami_local_password
volumes:
- umami-db-data:/var/lib/postgresql/data
healthcheck:
test: ['CMD-SHELL', 'pg_isready -U umami']
interval: 5s
timeout: 5s
retries: 5

umami:
image: ghcr.io/umami-software/umami:postgresql-latest
ports:
- '3001:3000'
environment:
DATABASE_URL: postgresql://umami:umami_local_password@umami-db:5432/umami
APP_SECRET: local_dev_secret
depends_on:
umami-db:
condition: service_healthy

volumes:
umami-db-data:
Loading