Switch base url from /console to /studio

This commit is contained in:
ernstmul
2025-04-01 11:24:36 +02:00
parent 654f544806
commit d36140a560
10 changed files with 82 additions and 9 deletions
+3 -1
View File
@@ -24,12 +24,14 @@ ARG PUBLIC_APPWRITE_ENDPOINT
ARG PUBLIC_GROWTH_ENDPOINT
ARG PUBLIC_STRIPE_KEY
ARG SENTRY_AUTH_TOKEN
ARG PUBLIC_PROJECT_PROFILE
ENV PUBLIC_APPWRITE_ENDPOINT=$PUBLIC_APPWRITE_ENDPOINT
ENV PUBLIC_GROWTH_ENDPOINT=$PUBLIC_GROWTH_ENDPOINT
ENV PUBLIC_CONSOLE_MODE=$PUBLIC_CONSOLE_MODE
ENV PUBLIC_STRIPE_KEY=$PUBLIC_STRIPE_KEY
ENV SENTRY_AUTH_TOKEN=$SENTRY_AUTH_TOKEN
ENV PUBLIC_PROJECT_PROFILE=$PUBLIC_PROJECT_PROFILE
ENV NODE_OPTIONS=--max_old_space_size=8192
RUN pnpm run build
@@ -38,5 +40,5 @@ FROM nginx:1.25-alpine
EXPOSE 80
COPY docker/nginx.conf /etc/nginx/conf.d/default.conf
COPY docker/nginx.$PUBLIC_PROJECT_PROFILE.conf /etc/nginx/conf.d/default.conf
COPY --from=build /app/build /usr/share/nginx/html/console
+39
View File
@@ -0,0 +1,39 @@
map $sent_http_content_type $expires {
# cache everything for 1 year
default 1y;
# html files shouldn't be cached for single-page applications
text/html off;
}
server {
listen 80;
server_name localhost;
# serve compressed file if filename.gz exists
gzip_static on;
location /studio {
root /usr/share/nginx/html;
index index.html index.htm;
try_files $uri /studio/index.html;
# Add cache headers
expires $expires;
add_header Pragma public;
add_header Cache-Control "public";
# Deny IE browsers from going into quirks mode
add_header X-UA-Compatible "IE=Edge";
# X-Frame-Options is to prevent from clickJacking attack
add_header X-Frame-Options SAMEORIGIN;
# This header enables the Cross-site scripting (XSS) filter
add_header X-XSS-Protection "1; mode=block;";
# disable content-type sniffing on some browsers.
add_header X-Content-Type-Options nosniff;
}
location / {
absolute_redirect off;
return 301 /studio;
}
}
+2
View File
@@ -33,6 +33,7 @@
"cron-parser": "^4.9.0",
"dayjs": "^1.11.13",
"deep-equal": "^2.2.3",
"dotenv": "^16.4.7",
"echarts": "^5.6.0",
"envfile": "^7.1.0",
"ignore": "^6.0.2",
@@ -47,6 +48,7 @@
},
"devDependencies": {
"@eslint/compat": "^1.2.7",
"@eslint/js": "^9.23.0",
"@melt-ui/pp": "^0.3.2",
"@melt-ui/svelte": "^0.86.5",
"@playwright/test": "^1.51.1",
+6
View File
@@ -47,6 +47,9 @@ importers:
deep-equal:
specifier: ^2.2.3
version: 2.2.3
dotenv:
specifier: ^16.4.7
version: 16.4.7
echarts:
specifier: ^5.6.0
version: 5.6.0
@@ -84,6 +87,9 @@ importers:
'@eslint/compat':
specifier: ^1.2.7
version: 1.2.7(eslint@9.23.0)
'@eslint/js':
specifier: ^9.23.0
version: 9.23.0
'@melt-ui/pp':
specifier: ^0.3.2
version: 0.3.2(@melt-ui/svelte@0.86.5(svelte@5.25.3))(svelte@5.25.3)
+3 -3
View File
@@ -5,9 +5,9 @@
<meta
name="description"
content="Appwrite is an open-source platform for building applications at any scale, using your preferred programming languages and tools." />
<link rel="icon" type="image/svg+xml" href="/console/logos/appwrite-icon.svg" />
<link rel="mask-icon" type="image/png" href="/console/logos/appwrite-icon.png" />
<link rel="stylesheet" href="/console/css/loading.css" />
<link rel="icon" type="image/svg+xml" href="/{project_profile}/logos/appwrite-icon.svg" />
<link rel="mask-icon" type="image/png" href="/{project_profile}/logos/appwrite-icon.png" />
<link rel="stylesheet" href="/{project_profile}/css/loading.css" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
%sveltekit.head%
</head>
+22 -1
View File
@@ -2,6 +2,7 @@ import { sequence } from '@sveltejs/kit/hooks';
import { handleErrorWithSentry, sentryHandle } from '@sentry/sveltekit';
import * as Sentry from '@sentry/sveltekit';
import { isCloud, isProd } from '$lib/system';
import type { Handle } from '@sveltejs/kit';
Sentry.init({
enabled: isCloud && isProd,
@@ -9,6 +10,26 @@ Sentry.init({
tracesSampleRate: 1.0
});
export const handle = sequence(sentryHandle());
const projectProfile = process.env.PUBLIC_PROJECT_PROFILE || 'console';
const dynamicHtmlTransform: Handle = async ({ event, resolve }) => {
let response = await resolve(event);
if (response.headers.get('content-type')?.includes('text/html')) {
let html = await response.text();
// Replace '/console/' dynamically with the project profile
html = html.replace(/\/{project_profile}\//g, `/${projectProfile}/`);
response = new Response(html, {
status: response.status,
headers: response.headers
});
}
return response;
};
export const handle = sequence(sentryHandle(), dynamicHtmlTransform);
export const handleError = handleErrorWithSentry();
+2 -2
View File
@@ -149,14 +149,14 @@
{#each preloadFonts as font}
<link rel="preload" href={font} as="font" type="font/woff2" crossorigin="anonymous" />
{/each}
<link rel="preload" as="style" type="text/css" href="/console/fonts/main.css" />
<link rel="preload" as="style" type="text/css" href={`${base}/fonts/main.css`} />
<link rel="stylesheet" href={`${base}/fonts/main.css`} />
{#if isCloud}
{#each preloadFontsCloud as font}
<link rel="preload" href={font} as="font" type="font/woff2" crossorigin="anonymous" />
{/each}
<link rel="preload" as="style" type="text/css" href="/console/fonts/cloud.css" />
<link rel="preload" as="style" type="text/css" href={`${base}/fonts/cloud.css`} />
<link rel="stylesheet" href={`${base}/fonts/cloud.css`} />
{/if}
</svelte:head>
+4 -1
View File
@@ -1,6 +1,9 @@
import adapter from '@sveltejs/adapter-static';
import { sveltePreprocess } from 'svelte-preprocess';
import { preprocessMeltUI, sequence } from '@melt-ui/pp';
import 'dotenv/config';
const projectProfile = process.env.PUBLIC_PROJECT_PROFILE || 'console';
/** @type {import('@sveltejs/kit').Config} */
const config = {
@@ -26,7 +29,7 @@ const config = {
precompress: true
}),
paths: {
base: '/console'
base: `/${projectProfile}`
}
},
vitePlugin: {
+1 -1
View File
@@ -12,7 +12,7 @@ export default defineConfig({
project: 'console'
}
}),
sveltekit()
sveltekit(),
],
optimizeDeps: {
include: ['echarts', 'prismjs']