Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
1 change: 1 addition & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ ZENDESK_KEY=<zendesk key>
GTM_ID=<google tag manager id>

BRANCH=optional (sets the edit path)
BASE_URL=optional (subpath the site is served from, no trailing slash; used by PR previews)
61 changes: 61 additions & 0 deletions .github/workflows/pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ name: PR build

on:
pull_request:
# `closed` is included so the preview deployment is torn down when the PR
# closes; the build/link-check job skips that event
types: [opened, reopened, synchronize, closed]
workflow_dispatch: # Allows manual triggering from the GitHub UI

permissions:
Expand All @@ -11,6 +14,7 @@ permissions:

jobs:
build:
if: github.event.action != 'closed'
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
Expand Down Expand Up @@ -116,3 +120,60 @@ jobs:
if (filtered.length > 0) {
core.setFailed("There are broken links in the documentation.");
}

# Deploys the built site to GitHub Pages under pr-preview/pr-<number>/ and
# posts a sticky comment on the PR with the preview URL; the preview is
# removed when the PR closes. Builds separately from the job above because
# the preview needs a different baseUrl than the link check. Fork PRs are
# skipped: they get neither secrets nor a writable GITHUB_TOKEN.
deploy-preview:
if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository
runs-on: ubuntu-latest
timeout-minutes: 30
# Concurrent runs for the same PR would race on pushing to gh-pages
concurrency: pr-preview-${{ github.ref }}
permissions:
contents: write
pull-requests: write
steps:
- uses: actions/checkout@v7
with:
# Images are Git LFS-tracked; skip fetching them on teardown, where
# the checkout is only needed so the action can push to gh-pages
lfs: ${{ github.event.action != 'closed' }}

- uses: actions/setup-node@v6
if: github.event.action != 'closed'
with:
node-version: 24
cache: npm

# The ADO registry requires auth even to install; the repo .npmrc is
# credential-less so creds go into ~/.npmrc here
- name: Authenticate to codat-npm feed
if: github.event.action != 'closed'
run: |
{
echo "//pkgs.dev.azure.com/codat/Codat/_packaging/codat-npm/npm/registry/:username=codat"
echo "//pkgs.dev.azure.com/codat/Codat/_packaging/codat-npm/npm/registry/:_password=${ADO_NPM_FEED_TOKEN}"
echo "//pkgs.dev.azure.com/codat/Codat/_packaging/codat-npm/npm/registry/:email=npm-requires-email@example.com"
} >> ~/.npmrc
env:
ADO_NPM_FEED_TOKEN: ${{ secrets.ADO_NPM_FEED_TOKEN }}

- name: Install dependencies
if: github.event.action != 'closed'
run: npm ci

- name: Build site for preview
if: github.event.action != 'closed'
run: npm run build
env:
GTM_ID: ${{ vars.GTM_ID }}
# GitHub Pages serves the preview from a subpath (no trailing slash)
BASE_URL: /codat-docs/pr-preview/pr-${{ github.event.number }}

- name: Deploy preview
uses: rossjrw/pr-preview-action@v1
with:
source-dir: ./build
7 changes: 6 additions & 1 deletion docusaurus.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,11 @@ import navbar from "./nav.config";
import redirects from "./redirects.config";

import { generateAPISitemaps } from "./src/utils/oas-sitemap.js";
import rehypeImageBaseUrl from "./src/utils/rehype-image-base-url.js";

const BASE_URL = "";
// PR preview deploys serve the site from a subpath on GitHub Pages, so the
// preview workflow overrides this. No trailing slash — baseUrl appends one.
const BASE_URL = process.env.BASE_URL ?? "";

require("dotenv").config();

Expand Down Expand Up @@ -129,6 +132,7 @@ const config = {
routeBasePath: "/",
sidebarPath: "./sidebars.js",
editUrl: `https://github.com/codatio/codat-docs/edit/${process.env?.BRANCH || "main"}/`,
rehypePlugins: [[rehypeImageBaseUrl, { baseUrl: `${BASE_URL}/` }]],
exclude: ["README.md"],
lastVersion: "current",
versions: {
Expand All @@ -140,6 +144,7 @@ const config = {
},
blog: {
showReadingTime: true,
rehypePlugins: [[rehypeImageBaseUrl, { baseUrl: `${BASE_URL}/` }]],
blogTitle: "Codat updates",
blogDescription: "Engineering and product updates from Codat.",
postsPerPage: 10,
Expand Down
6 changes: 5 additions & 1 deletion src/components/Api/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React, { useState, Suspense } from "react";
import { Helmet } from "react-helmet";

import BrowserOnly from "@docusaurus/BrowserOnly";
import useBaseUrl from "@docusaurus/useBaseUrl";

import Layout from "@theme/Layout";
import Navbar from "@theme/Navbar";
Expand All @@ -21,6 +22,9 @@ const Api = ({
socialBanner = "https://docs.codat.io/img/meta/codat-bg.png",
}) => {
const [menuOpen, setMenuOpen] = useState(false);
// The OAS specs live in static/, so the fetch URL must respect baseUrl for
// deploys served from a subpath (e.g. PR previews)
const specUrl = useBaseUrl(url);

return (
<Layout title={title}>
Expand Down Expand Up @@ -48,7 +52,7 @@ const Api = ({
<BrowserOnly>
{() => (
<Suspense fallback={Fallback}>
<LazyStoplight apiDescriptionUrl={url} />
<LazyStoplight apiDescriptionUrl={specUrl} />
</Suspense>
)}
</BrowserOnly>
Expand Down
24 changes: 18 additions & 6 deletions src/components/Cards/index.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,20 @@
import { useBaseUrlUtils } from "@docusaurus/useBaseUrl";

// Callers pass absolute image/link paths (e.g. /img/...), which bypass
// baseUrl and break deploys served from a subpath (e.g. PR previews);
// external URLs pass through withBaseUrl untouched
const Card = (props) => {
const { image, icon: Icon, title, children, className } = props;
const { withBaseUrl } = useBaseUrlUtils();

return (
<li className={`card ${className}`}>
<div className="header">
{Icon ? <Icon /> : <img src={image} className="mini-icon" />}
{Icon ? (
<Icon />
) : (
<img src={withBaseUrl(image)} className="mini-icon" />
)}

<h3>{title}</h3>
</div>
Expand All @@ -16,40 +26,42 @@ const Card = (props) => {

const CardTwo = (props) => {
const { image, title, link, linkText, children, className } = props;
const { withBaseUrl } = useBaseUrlUtils();

return (
<li className={`card two ${className}`}>
<div className="header">
<img src={image} className="mini-icon" />
<img src={withBaseUrl(image)} className="mini-icon" />

<h3>{title}</h3>
</div>

{children}

<p>
<a href={link}>{linkText} →</a>
<a href={withBaseUrl(link)}>{linkText} →</a>
</p>
</li>
);
};

const MiniCard = (props) => {
const { image, title, subtitle, link, children, className } = props;
const { withBaseUrl } = useBaseUrlUtils();

return (
<li className={`card mini ${className}`}>
<div className="card-row">
<div className="header">
<a href={link}>
<img src={image} className="icon usecase" />
<a href={withBaseUrl(link)}>
<img src={withBaseUrl(image)} className="icon usecase" />
</a>
</div>

<div className="content">
<h4>{title}</h4>
<p>
<a href={link}>{subtitle} →</a>
<a href={withBaseUrl(link)}>{subtitle} →</a>
</p>
</div>
</div>
Expand Down
9 changes: 8 additions & 1 deletion src/components/ClientLibraries/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import React from "react";
import { useBaseUrlUtils } from "@docusaurus/useBaseUrl";

const repoBaseUrl = "https://github.com/codatio/client-sdk-";
const repoProductTMP = "/tree/main/bank-feeds";
Expand Down Expand Up @@ -93,6 +94,9 @@ const getShieldUrl = (productName, language) => {

const ClientLibraries = ({ productName }) => {
const productUrl = !productName ? "" : "/tree/main/" + productName;
// The language icons are absolute /img/ paths, which bypass baseUrl and
// break deploys served from a subpath (e.g. PR previews)
const { withBaseUrl } = useBaseUrlUtils();
return (
<ul className="card-container mini">
{languages.map((language, i) => {
Expand All @@ -104,7 +108,10 @@ const ClientLibraries = ({ productName }) => {
href={repoBaseUrl + language.name + productUrl}
target="_blank"
>
<img src={language.icon} className="icon usecase" />
<img
src={withBaseUrl(language.icon)}
className="icon usecase"
/>
</a>
</div>

Expand Down
6 changes: 5 additions & 1 deletion src/components/Clients/index.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
import React from "react";
import { useBaseUrlUtils } from "@docusaurus/useBaseUrl";

import styles from "./styles.module.scss";

const Client = (props) => {
const { path, name, scale } = props;
// Callers pass absolute /img/ paths, which bypass baseUrl and break
// deploys served from a subpath (e.g. PR previews)
const { withBaseUrl } = useBaseUrlUtils();

return (
<div className={styles.client}>
<img
src={path}
src={withBaseUrl(path)}
alt={`${name} logo`}
style={
scale
Expand Down
10 changes: 8 additions & 2 deletions src/components/PageHeader/index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React from "react";
import clsx from "clsx";
import { useColorMode } from "@docusaurus/theme-common";
import { useBaseUrlUtils } from "@docusaurus/useBaseUrl";

import { ModalController } from "../Modal";

Expand Down Expand Up @@ -35,7 +36,12 @@ const PageHeader = ({
videoText,
}) => {
const { colorMode } = useColorMode();
const resolvedIcon = iconDark && colorMode === "dark" ? iconDark : icon;
// icon/img arrive as absolute paths from frontmatter (banner_image etc.),
// which bypass baseUrl and break deploys served from a subpath
const { withBaseUrl } = useBaseUrlUtils();
const resolvedIcon = withBaseUrl(
iconDark && colorMode === "dark" ? iconDark : icon,
);

return (
<div className={clsx(styles.wrapper, className)}>
Expand All @@ -62,7 +68,7 @@ const PageHeader = ({
{videoUrl && <BannerVideo text={videoText} url={videoUrl} />}
</div>

{img && <img src={img} className={styles.heroImg} alt="" />}
{img && <img src={withBaseUrl(img)} className={styles.heroImg} alt="" />}
</div>
);
};
Expand Down
24 changes: 14 additions & 10 deletions src/components/Products/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import React from "react";
import { useColorMode } from "@docusaurus/theme-common";
import { useBaseUrlUtils } from "@docusaurus/useBaseUrl";

const other = [
{
Expand Down Expand Up @@ -104,6 +105,9 @@ const allProducts = [

const Products = ({ mini, products, verbose }) => {
const { colorMode } = useColorMode();
// The logo/link paths above are absolute, which bypasses baseUrl and
// breaks deploys served from a subpath (e.g. PR previews)
const { withBaseUrl } = useBaseUrlUtils();
const validProducts = !products
? allProducts
: products
Expand All @@ -130,15 +134,15 @@ const Products = ({ mini, products, verbose }) => {
<div className="card-row">
<div className="header">
<a
href={product.link}
href={withBaseUrl(product.link)}
className={`icon-wrapper product animated ${product.slug}`}
>
<img
src={
src={withBaseUrl(
colorMode === "dark" && product.logoDark
? product.logoDark
: product.logo
}
: product.logo,
)}
className="icon product"
/>
</a>
Expand All @@ -147,7 +151,7 @@ const Products = ({ mini, products, verbose }) => {
<div className="content">
<h4>{product.name}</h4>
<p>
<a href={product.link}>Explore solution →</a>
<a href={withBaseUrl(product.link)}>Explore solution →</a>
</p>
</div>
</div>
Expand All @@ -167,23 +171,23 @@ const Products = ({ mini, products, verbose }) => {
<li key={i} className="card">
<div className="header">
<a
href={product.link}
href={withBaseUrl(product.link)}
className={`icon-wrapper product animated ${product.slug}`}
>
<img
src={
src={withBaseUrl(
colorMode === "dark" && product.logoDark
? product.logoDark
: product.logo
}
: product.logo,
)}
className="icon product"
/>
</a>
</div>
<h3>{product.name}</h3>
<p>{product.description}</p>
<p>
<a href={product.link}>{product.linkText}</a>
<a href={withBaseUrl(product.link)}>{product.linkText}</a>
</p>
</li>
);
Expand Down
3 changes: 2 additions & 1 deletion src/pages/support/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import React from "react";
import Link from "@docusaurus/Link";
import GearFinanceDownIcon from "@components/GearFinanceDownIcon";
import FeatureBullet from "@components/FeatureBullet";
import Layout from "@theme/Layout";
Expand All @@ -24,7 +25,7 @@ const RaiseSupportTicket = () => {
</div>
<p>
Raise a technical issue with our support team{" "}
<a href="/raise-support-ticket">here</a>.
<Link to="/raise-support-ticket">here</Link>.
</p>
</li>
<li className="card">
Expand Down
4 changes: 2 additions & 2 deletions src/theme/BlogSidebar/Desktop/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,9 @@ export default function BlogSidebarDesktop({ sidebar }: Props): JSX.Element {
))
: "No deprecations"}
</ul>
<a href="/updates/tags/deprecation" className={styles.sidebarItemList}>
<Link to="/updates/tags/deprecation" className={styles.sidebarItemList}>
See all...
</a>
</Link>

<br />
<hr />
Expand Down
Loading
Loading