Skip to content

Commit

Permalink
add env var PLAUSIBLE_DOMAIN and set it for every mirror
Browse files Browse the repository at this point in the history
  • Loading branch information
nemanjam committed Sep 29, 2024
1 parent cbe64aa commit 69fe30f
Show file tree
Hide file tree
Showing 17 changed files with 70 additions and 14 deletions.
6 changes: 5 additions & 1 deletion .env.development.example
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,9 @@ SITE_URL=http://localhost:3000
# always true in development, set only on prod build
# PREVIEW_MODE=

# plausible analytics url
# Plausible analytics url
PLAUSIBLE_SCRIPT_URL=

# for mirrors, hostname set in Plausible dashboard
# if not set, defaults to SITE_URL without https://
PLAUSIBLE_DOMAIN=
4 changes: 4 additions & 0 deletions .env.production.example
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,7 @@ PREVIEW_MODE=

# plausible analytics url
PLAUSIBLE_SCRIPT_URL=

# for mirrors, hostname set in Plausible dashboard
# if not set, defaults to SITE_URL without https://
PLAUSIBLE_DOMAIN=nemanjamitic.com
3 changes: 3 additions & 0 deletions .github/workflows/bash__deploy-nginx.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ name: Deploy Nginx with bash file

on:
push:
# this one is enabled
branches:
- 'main'
tags:
Expand All @@ -15,6 +16,8 @@ env:
SITE_URL: 'https://nemanjamitic.com'
PLAUSIBLE_SCRIPT_URL: 'https://plausible.arm1.nemanjamitic.com/js/script.js'
SSH_ALIAS: arm1
# can be omitted for main domain, will default to SITE_URL
# PLAUSIBLE_DOMAIN: 'nemanjamitic.com'

jobs:
deploy:
Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/default__build-push-docker.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ env:
SITE_URL_ARM64: 'https://nmc-docker.arm1.nemanjamitic.com'
SITE_URL_AMD64: 'https://nmc-docker.local.nemanjamitic.com'
PLAUSIBLE_SCRIPT_URL: 'https://plausible.arm1.nemanjamitic.com/js/script.js'
PLAUSIBLE_DOMAIN: 'nemanjamitic.com'

jobs:
build:
Expand Down Expand Up @@ -87,6 +88,7 @@ jobs:
build-args: |
"ARG_SITE_URL=${{ env.SITE_URL }}"
"ARG_PLAUSIBLE_SCRIPT_URL=${{ env.PLAUSIBLE_SCRIPT_URL }}"
"ARG_PLAUSIBLE_DOMAIN=${{ env.PLAUSIBLE_DOMAIN }}"
push: true
tags: ${{ secrets.DOCKER_USERNAME }}/${{ env.IMAGE_NAME }}:latest
# disabled metadata step
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/default__deploy-nginx.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ on:
env:
SITE_URL: 'https://nemanjamitic.com'
PLAUSIBLE_SCRIPT_URL: 'https://plausible.arm1.nemanjamitic.com/js/script.js'
PLAUSIBLE_DOMAIN: 'nemanjamitic.com'

jobs:
deploy:
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/gh-pages__deploy-astro.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ permissions:
env:
SITE_URL: 'https://nemanjam.github.io'
PLAUSIBLE_SCRIPT_URL: 'https://plausible.arm1.nemanjamitic.com/js/script.js'
PLAUSIBLE_DOMAIN: 'nemanjamitic.com'

jobs:
# build with astro action, unusable for monorepo
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/gh-pages__deploy-manual.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ permissions:
env:
SITE_URL: 'https://nemanjam.github.io'
PLAUSIBLE_SCRIPT_URL: 'https://plausible.arm1.nemanjamitic.com/js/script.js'
PLAUSIBLE_DOMAIN: 'nemanjamitic.com'

jobs:
build-manual:
Expand Down
2 changes: 2 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ services:
ARG_SITE_URL: 'http://localhost:8080'
# make separate script with localhost enabled
ARG_PLAUSIBLE_SCRIPT_URL: 'https://plausible.arm1.nemanjamitic.com/js/script.js'
# will trigger analytics
ARG_PLAUSIBLE_DOMAIN: 'nemanjamitic.com'

# platform: linux/arm64
platform: linux/amd64
Expand Down
4 changes: 4 additions & 0 deletions docker/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ ARG ARG_PLAUSIBLE_SCRIPT_URL
ENV PLAUSIBLE_SCRIPT_URL=$ARG_PLAUSIBLE_SCRIPT_URL
RUN echo "PLAUSIBLE_SCRIPT_URL=$PLAUSIBLE_SCRIPT_URL"

ARG ARG_PLAUSIBLE_DOMAIN
ENV PLAUSIBLE_DOMAIN=$ARG_PLAUSIBLE_DOMAIN
RUN echo "PLAUSIBLE_DOMAIN=$PLAUSIBLE_DOMAIN"

RUN yarn build

FROM nginx:stable-alpine3.17-slim AS runtime
Expand Down
1 change: 1 addition & 0 deletions docs/working-notes/todo3.md
Original file line number Diff line number Diff line change
Expand Up @@ -550,5 +550,6 @@ restructure folders, folder name, mdx and images in same folder
content collections to content layer
fix plausible for all subdomains
gallery astro image
prettyPrintObject in_ dev works after page load, ok
------------
```
8 changes: 4 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@
"start": "serve ./dist",
"preview": "astro preview",
"build": "astro build",
"build:nginx": "SITE_URL='https://nemanjamitic.com' PLAUSIBLE_SCRIPT_URL='https://plausible.arm1.nemanjamitic.com/js/script.js' astro build",
"build:nginx:local": "SITE_URL='https://blog.local.nemanjamitic.com' PLAUSIBLE_SCRIPT_URL='https://plausible.arm1.nemanjamitic.com/js/script.js' astro build",
"build:nginx": "SITE_URL='https://nemanjamitic.com' PLAUSIBLE_SCRIPT_URL='https://plausible.arm1.nemanjamitic.com/js/script.js' PLAUSIBLE_DOMAIN='nemanjamitic.com' astro build",
"build:nginx:local": "SITE_URL='https://blog.local.nemanjamitic.com' PLAUSIBLE_SCRIPT_URL='https://plausible.arm1.nemanjamitic.com/js/script.js' PLAUSIBLE_DOMAIN='nemanjamitic.com' astro build",
"astro": "astro",
"sync": "astro sync",
"lint": "eslint --ext .astro,.tsx,.ts,.js,.mdx src",
Expand All @@ -19,8 +19,8 @@
"deploy:nginx:local": "bash scripts/deploy-nginx.sh '~/traefik-proxy/apps/nmc-nginx-with-volume/website' lxc11",
"deploy:docker": "bash scripts/deploy-docker.sh arm1 '~/traefik-proxy/apps/nmc-docker' nemanjamitic/nemanjam.github.io",
"deploy:docker:local": "bash scripts/deploy-docker.sh lxc11 '~/traefik-proxy/apps/nmc-docker' nemanjamitic/nemanjam.github.io",
"docker:build:push:arm": "docker buildx build -f ./docker/Dockerfile -t nemanjamitic/nemanjam.github.io --build-arg ARG_SITE_URL='https://nmc-docker.arm1.nemanjamitic.com' --build-arg ARG_PLAUSIBLE_SCRIPT_URL='https://plausible.arm1.nemanjamitic.com/js/script.js' --platform linux/arm64 --push .",
"docker:build:push:x86": "docker buildx build -f ./docker/Dockerfile -t nemanjamitic/nemanjam.github.io --build-arg ARG_SITE_URL='https://nmc-docker.local.nemanjamitic.com' --build-arg ARG_PLAUSIBLE_SCRIPT_URL='https://plausible.arm1.nemanjamitic.com/js/script.js' --platform linux/amd64 --push .",
"docker:build:push:arm": "docker buildx build -f ./docker/Dockerfile -t nemanjamitic/nemanjam.github.io --build-arg ARG_SITE_URL='https://nmc-docker.arm1.nemanjamitic.com' --build-arg ARG_PLAUSIBLE_SCRIPT_URL='https://plausible.arm1.nemanjamitic.com/js/script.js' --build-arg ARG_PLAUSIBLE_DOMAIN='nemanjamitic.com' --platform linux/arm64 --push .",
"docker:build:push:x86": "docker buildx build -f ./docker/Dockerfile -t nemanjamitic/nemanjam.github.io --build-arg ARG_SITE_URL='https://nmc-docker.local.nemanjamitic.com' --build-arg ARG_PLAUSIBLE_SCRIPT_URL='https://plausible.arm1.nemanjamitic.com/js/script.js' --build-arg ARG_PLAUSIBLE_DOMAIN='nemanjamitic.com' --platform linux/amd64 --push .",
"docker:push": "docker push nemanjamitic/nemanjam.github.io",
"dc:up": "docker compose up --build --force-recreate -d"
},
Expand Down
7 changes: 3 additions & 4 deletions src/components/BaseHead.astro
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,8 @@ import { filterUndefined } from '@/utils/objects';
import type { Metadata } from '@/types/common';
const { AUTHOR_NAME, PLAUSIBLE_SCRIPT_URL } = CONFIG_CLIENT;
const { AUTHOR_NAME, PLAUSIBLE_SCRIPT_URL, PLAUSIBLE_DOMAIN } = CONFIG_CLIENT;
// this must be the same for all mirrors
const PLAUSIBLE_DATA_DOMAIN = 'nemanjamitic.com';
export interface BaseHeadProps {
metadata: Metadata;
}
Expand Down Expand Up @@ -109,11 +107,12 @@ const ogImageUrl = new URL(image, url);
PLAUSIBLE_SCRIPT_URL && (
<>
<link rel="preconnect" href={PLAUSIBLE_SCRIPT_URL} />
{/* PLAUSIBLE_DOMAIN must be the same for all mirrors */}
<script
defer
type="text/partytown"
data-domain={PLAUSIBLE_DATA_DOMAIN}
src={PLAUSIBLE_SCRIPT_URL}
data-domain={PLAUSIBLE_DOMAIN}
/>
</>
)
Expand Down
3 changes: 2 additions & 1 deletion src/config/client.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { PLAUSIBLE_SCRIPT_URL, SITE_URL } from 'astro:env/client';
import { PLAUSIBLE_DOMAIN, PLAUSIBLE_SCRIPT_URL, SITE_URL } from 'astro:env/client';

import { configClientSchema } from '@/schemas/config';
import { validateData } from '@/utils/validation';
Expand All @@ -11,6 +11,7 @@ const configClientData: ConfigClientType = {
SITE_TITLE: 'Nemanja Mitic',
SITE_DESCRIPTION: 'I am Nemanja, full stack developer',
PLAUSIBLE_SCRIPT_URL,
PLAUSIBLE_DOMAIN,
PAGE_SIZE_POST_CARD: 3,
PAGE_SIZE_POST_CARD_SMALL: 6,
MORE_POSTS_COUNT: 3,
Expand Down
8 changes: 8 additions & 0 deletions src/config/process-env.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { envField } from 'astro/config';
import dotenv from 'dotenv';

import { nodeEnvValues, processEnvSchema } from '../schemas/config';
import { getHostnameFromUrl } from '../utils/urls';
import { validateData } from '../utils/validation';

import type { ProcessEnvType } from '../types/config';
Expand Down Expand Up @@ -32,6 +33,7 @@ const processEnvData: ProcessEnvType = {
PREVIEW_MODE: process.env.PREVIEW_MODE,
SITE_URL: process.env.SITE_URL,
PLAUSIBLE_SCRIPT_URL: process.env.PLAUSIBLE_SCRIPT_URL,
PLAUSIBLE_DOMAIN: process.env.PLAUSIBLE_DOMAIN,
};

export const PROCESS_ENV = validateData(processEnvData, processEnvSchema);
Expand Down Expand Up @@ -62,5 +64,11 @@ export const envSchema = {
access: 'public',
optional: true,
}),
PLAUSIBLE_DOMAIN: envField.string({
context: 'client',
access: 'public',
optional: true,
default: getHostnameFromUrl(PROCESS_ENV.SITE_URL),
}),
},
};
21 changes: 19 additions & 2 deletions src/schemas/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ export const booleanValues = ['true', 'false', ''] as const;
export const modeValues = ['light', 'dark'] as const;
export const themeValues = ['default-light', 'default-dark', 'green-light', 'green-dark'] as const;

const domainSubdomainRegex =
/^(?!-)[A-Za-z0-9-]{1,63}(?<!-)(\.(?!-)[A-Za-z0-9-]{1,63}(?<!-))*\.[A-Za-z]{2,}$/;

/** runs after astro:env check in astro.config.ts */
export const processEnvSchema = z.object({
NODE_ENV: z.enum(nodeEnvValues),
PREVIEW_MODE: z
Expand All @@ -15,14 +19,27 @@ export const processEnvSchema = z.object({
// ensure no trailing slash
SITE_URL: z.string().url().regex(/[^/]$/, 'SITE_URL should not end with a slash "/"'),
PLAUSIBLE_SCRIPT_URL: z.string().url().or(z.literal('')).optional(),
PLAUSIBLE_DOMAIN: z
.string()
.or(z.enum(['', 'localhost'])) // for types
.optional()
.refine(
// check regex this way
(value) =>
value === undefined ||
value === '' ||
value === 'localhost' || // astro:env default
domainSubdomainRegex.test(value),
(value) => ({ message: `Invalid hostname for PLAUSIBLE_DOMAIN 1: ${value}` })
),
});

export const configServerSchema = processEnvSchema
.omit({ SITE_URL: true, PREVIEW_MODE: true, PLAUSIBLE_SCRIPT_URL: true })
.omit({ SITE_URL: true, PREVIEW_MODE: true, PLAUSIBLE_SCRIPT_URL: true, PLAUSIBLE_DOMAIN: true })
.extend({ PREVIEW_MODE: z.boolean() }); // here its boolean, not 'true' | 'false'

export const configClientSchema = processEnvSchema
.pick({ SITE_URL: true, PLAUSIBLE_SCRIPT_URL: true })
.pick({ SITE_URL: true, PLAUSIBLE_SCRIPT_URL: true, PLAUSIBLE_DOMAIN: true })
.merge(
z.object({
SITE_TITLE: z.string().min(1),
Expand Down
1 change: 1 addition & 0 deletions src/utils/urls.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const getHostnameFromUrl = (url: string): string => new URL(url).hostname;
11 changes: 9 additions & 2 deletions src/utils/validation.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,18 @@
import { z, ZodSchema } from 'zod';

export const zodErrorToString = (error: z.ZodError): string => {
return error.errors.map((err: z.ZodIssue) => `${err.path.join('.')}: ${err.message}`).join(', ');
};

export const validateData = <T extends ZodSchema>(config: z.infer<T>, schema: T): z.infer<T> => {
const parsedConfig = schema.safeParse(config);

if (!parsedConfig.success) {
console.error('Zod validation failed: ', parsedConfig.error.flatten().fieldErrors);
throw new Error('Zod validation failed');
const zodErrors = zodErrorToString(parsedConfig.error);
const errorMessage = `Zod validation failed: , ${zodErrors}`;

console.error(errorMessage);
throw new Error(errorMessage);
}

const { data: parsedConfigData } = parsedConfig;
Expand Down

0 comments on commit 69fe30f

Please sign in to comment.