diff --git a/frontend/Dockerfile b/frontend/Dockerfile index 4543977..5603a97 100644 --- a/frontend/Dockerfile +++ b/frontend/Dockerfile @@ -1,7 +1,10 @@ FROM node:20-alpine AS builder WORKDIR /app -ARG VITE_PUBLIC_SITE_URL="https://www.thetriangle.org" +# Baked in at build time (Vite inlines import.meta.env), so this is the origin +# every "View Live" link and permalink preview in the published image points at. +# Override with --build-arg to publish an image aimed at another site. +ARG VITE_PUBLIC_SITE_URL="https://dev.thetriangle.org" ENV VITE_PUBLIC_SITE_URL=${VITE_PUBLIC_SITE_URL} COPY package.json package-lock.json ./ diff --git a/frontend/src/auth/urls.ts b/frontend/src/auth/urls.ts index df3a2d0..8535c00 100644 --- a/frontend/src/auth/urls.ts +++ b/frontend/src/auth/urls.ts @@ -10,8 +10,11 @@ export function authBaseUrl() { return trimTrailingSlashes(import.meta.env.VITE_AUTH_BASE_URL ?? "") } -// Public-facing site origin, used to build article permalinks (e.g. so Yoast can -// tell internal links from outbound ones). +// Public-facing site origin, used for article permalinks (e.g. so Yoast can +// tell internal links from outbound ones) and for the "View Live" links. +// Defaults to the dev site: the CMS is not yet driving production, so an +// unconfigured build pointing at www would send editors to pages that do not +// reflect what they just saved. export function publicSiteUrl() { - return trimTrailingSlashes(import.meta.env.VITE_PUBLIC_SITE_URL ?? "https://www.thetriangle.org") + return trimTrailingSlashes(import.meta.env.VITE_PUBLIC_SITE_URL ?? "https://dev.thetriangle.org") } diff --git a/frontend/src/pages/DashboardPage.tsx b/frontend/src/pages/DashboardPage.tsx index d47fb10..2c54292 100644 --- a/frontend/src/pages/DashboardPage.tsx +++ b/frontend/src/pages/DashboardPage.tsx @@ -1,6 +1,7 @@ import { useEffect, useState } from "react" import { useNavigate } from "react-router-dom" import { useApiFetch } from "../hooks/useApiFetch" +import { publicSiteUrl } from "../auth/urls" import { useSessionAuth } from "../auth/sessionAuthContext" import { FileText, @@ -336,7 +337,7 @@ export default function DashboardPage() { variant="outline" size="sm" className="gap-1.5" - onClick={() => window.open("https://www.thetriangle.org", "_blank", "noopener,noreferrer")} + onClick={() => window.open(publicSiteUrl(), "_blank", "noopener,noreferrer")} > View site diff --git a/frontend/src/pages/articleView.tsx b/frontend/src/pages/articleView.tsx index f7a3d9b..49c1b58 100644 --- a/frontend/src/pages/articleView.tsx +++ b/frontend/src/pages/articleView.tsx @@ -1,6 +1,7 @@ -import { useEffect, useState } from "react" +import { useEffect, useMemo, useState } from "react" import { ExternalLink, Search, Pencil, Plus, Trash2, X, ChevronFirst, ChevronLast, ChevronLeft, ChevronRight, Undo2 } from "lucide-react" import { useNavigate } from "react-router-dom" +import { publicSiteUrl } from "../auth/urls" import { useApiFetch } from "../hooks/useApiFetch" type ArticleStatus = "Published" | "Draft" | "Archived" @@ -103,6 +104,9 @@ const writeSessionJSON = (key: string, value: unknown) => { function ArticleView({ pageTitle = "Articles", fixedType, excludeType }: ArticleViewProps) { const navigate = useNavigate() const apiFetch = useApiFetch() + // Same origin the comments view and the editor's permalink preview use, so + // "View Live" cannot point at a different site than the rest of the CMS. + const siteUrl = useMemo(() => publicSiteUrl(), []) const storageKeyBase = `articleView:${fixedType ?? "all"}:${excludeType ?? "none"}` const uiStateKey = `${storageKeyBase}:ui` const resultsCacheKey = `${storageKeyBase}:results` @@ -603,7 +607,7 @@ function ArticleView({ pageTitle = "Articles", fixedType, excludeType }: Article {activeTab !== "trash" && item.status === "Published" && (