diff --git a/.env.development.example b/.env.development.example
index 906b7f1..f0cb671 100644
--- a/.env.development.example
+++ b/.env.development.example
@@ -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=
diff --git a/.env.production.example b/.env.production.example
index b83fc74..828816e 100644
--- a/.env.production.example
+++ b/.env.production.example
@@ -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
\ No newline at end of file
diff --git a/.github/workflows/bash__deploy-nginx.yml b/.github/workflows/bash__deploy-nginx.yml
index ddc0767..c28e547 100644
--- a/.github/workflows/bash__deploy-nginx.yml
+++ b/.github/workflows/bash__deploy-nginx.yml
@@ -2,6 +2,7 @@ name: Deploy Nginx with bash file
on:
push:
+ # this one is enabled
branches:
- 'main'
tags:
@@ -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:
diff --git a/.github/workflows/default__build-push-docker.yml b/.github/workflows/default__build-push-docker.yml
index aa0654a..dad69e4 100644
--- a/.github/workflows/default__build-push-docker.yml
+++ b/.github/workflows/default__build-push-docker.yml
@@ -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:
@@ -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
diff --git a/.github/workflows/default__deploy-nginx.yml b/.github/workflows/default__deploy-nginx.yml
index 4a1465b..e7ff8f0 100644
--- a/.github/workflows/default__deploy-nginx.yml
+++ b/.github/workflows/default__deploy-nginx.yml
@@ -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:
diff --git a/.github/workflows/gh-pages__deploy-astro.yml b/.github/workflows/gh-pages__deploy-astro.yml
index 1312917..7151d79 100644
--- a/.github/workflows/gh-pages__deploy-astro.yml
+++ b/.github/workflows/gh-pages__deploy-astro.yml
@@ -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
diff --git a/.github/workflows/gh-pages__deploy-manual.yml b/.github/workflows/gh-pages__deploy-manual.yml
index 416a55a..7247d2d 100644
--- a/.github/workflows/gh-pages__deploy-manual.yml
+++ b/.github/workflows/gh-pages__deploy-manual.yml
@@ -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:
diff --git a/docker-compose.yml b/docker-compose.yml
index cb28779..75a3654 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -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
diff --git a/docker/Dockerfile b/docker/Dockerfile
index f33ca2a..8d623f8 100644
--- a/docker/Dockerfile
+++ b/docker/Dockerfile
@@ -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
diff --git a/docs/working-notes/todo3.md b/docs/working-notes/todo3.md
index b567783..6211d04 100644
--- a/docs/working-notes/todo3.md
+++ b/docs/working-notes/todo3.md
@@ -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
------------
```
diff --git a/package.json b/package.json
index 6b021bc..16a149c 100644
--- a/package.json
+++ b/package.json
@@ -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",
@@ -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"
},
diff --git a/src/components/BaseHead.astro b/src/components/BaseHead.astro
index b7bba8b..22b5675 100644
--- a/src/components/BaseHead.astro
+++ b/src/components/BaseHead.astro
@@ -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;
}
@@ -109,11 +107,12 @@ const ogImageUrl = new URL(image, url);
PLAUSIBLE_SCRIPT_URL && (
<>
+ {/* PLAUSIBLE_DOMAIN must be the same for all mirrors */}
>
)
diff --git a/src/config/client.ts b/src/config/client.ts
index 51deccc..72d8f7b 100644
--- a/src/config/client.ts
+++ b/src/config/client.ts
@@ -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';
@@ -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,
diff --git a/src/config/process-env.ts b/src/config/process-env.ts
index fba19e9..678d325 100644
--- a/src/config/process-env.ts
+++ b/src/config/process-env.ts
@@ -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';
@@ -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);
@@ -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),
+ }),
},
};
diff --git a/src/schemas/config.ts b/src/schemas/config.ts
index 3fc7290..93f661f 100644
--- a/src/schemas/config.ts
+++ b/src/schemas/config.ts
@@ -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}(?
+ 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),
diff --git a/src/utils/urls.ts b/src/utils/urls.ts
new file mode 100644
index 0000000..17660f4
--- /dev/null
+++ b/src/utils/urls.ts
@@ -0,0 +1 @@
+export const getHostnameFromUrl = (url: string): string => new URL(url).hostname;
diff --git a/src/utils/validation.ts b/src/utils/validation.ts
index 03df918..455e06b 100644
--- a/src/utils/validation.ts
+++ b/src/utils/validation.ts
@@ -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 = (config: z.infer, schema: T): z.infer => {
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;