Skip to content
Merged
Show file tree
Hide file tree
Changes from 16 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
2 changes: 1 addition & 1 deletion .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@ ALGOLIA_API_KEY=algolia_api_key
ALGOLIA_APPLICATION_ID=algolia_application_id
DIRECTUS_URL=https://marketing-directus-url.com
GOOGLE_TAG_MANAGER_ID=GTM-PTLT3GH
NUXT_UI_PRO_LICENSE=nuxt_ui_pro_license_key_needed_to_build
POSTHOG_API_HOST=https://directus.io/ingest
POSTHOG_API_KEY=phc_secret_key_here
NUXT_PUBLIC_SITE_URL=https://directus.io
9 changes: 9 additions & 0 deletions .githooks/pre-commit
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#!/bin/sh
set -e

if ! command -v pnpm >/dev/null 2>&1; then
echo "warning: pnpm not found; skipping stable ID hook" >&2
exit 0
fi

pnpm stable-ids:ensure --staged
22 changes: 22 additions & 0 deletions .githooks/pre-push
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#!/bin/sh
set -e

if ! git fetch origin main --quiet; then
echo "warning: failed to fetch origin/main; using local ref for redirect check" >&2
fi

if git rev-parse --verify origin/main >/dev/null 2>&1; then
base_ref="origin/main"
elif git rev-parse --verify main >/dev/null 2>&1; then
base_ref="main"
else
echo "warning: no origin/main or main ref found; skipping redirect check" >&2
exit 0
fi

if git diff --quiet "$base_ref"...HEAD -- content redirects.json content.config.ts; then
exit 0
fi

echo "Checking redirects for docs changes..."
pnpm redirects:check -- --base "$base_ref"
16 changes: 15 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ Welcome! This is the repo for [Directus' documentation](https://docs.directus.io

### Requirements

- Node.js 22
- Node.js 22.18 or later
- pnpm

### Install Dependencies
Expand Down Expand Up @@ -47,6 +47,20 @@ pnpm dev
pnpm build
```

### Repository Tooling

The repository includes scripts that keep docs routes stable when files move.

```bash
pnpm stable-ids:ensure # Add missing stableId frontmatter
pnpm stable-ids:check # Validate stableId frontmatter
pnpm redirects:sync # Update redirects.json for moved pages
pnpm redirects:check # Check redirect coverage without writing files
pnpm typecheck:scripts # Type check repository scripts
```

`pnpm install` configures `.githooks` for the repository when no custom `core.hooksPath` is set. The pre-commit hook can add missing `stableId` values to staged docs files. The pre-push hook checks redirects when docs content, redirect configuration, or content configuration changes.

## ☁️ Deploying the Docs

The documentation automatically deploys to Vercel when changes are merged into the main branch. Simply:
Expand Down
9 changes: 4 additions & 5 deletions app/app.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,6 @@ export default defineAppConfig({
wrapper: '[&_pre>code]:!bg-transparent',
},
},
},

uiPro: {
page: {
slots: {
root: 'lg:gap-8',
Expand Down Expand Up @@ -190,11 +187,13 @@ export default defineAppConfig({
cta: {
cloud: {
link: 'https://directus.cloud',
description: 'Everything you need to start building. Provisioned in 90 seconds.',
description:
'Everything you need to start building. Provisioned in 90 seconds.',
cta: 'Get Started',
},
newsletter: {
description: 'Get once-a-month release notes & real‑world code tips...no fluff. 🐰',
description:
'Get once-a-month release notes & real‑world code tips...no fluff. 🐰',
form: {
hsPortal: 20534155,
hsForm: 'd57a69e4-6f43-4768-a600-5f7d30306260',
Expand Down
4 changes: 2 additions & 2 deletions app/app.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ const { data: navigation } = useAsyncData('content-navigation', () => queryColle
provide('openapi', spec);
provide('navigation', navigation as Ref<ContentNavigationItem[]>);

defineOgImage({
url: '/og-image.png',
defineOgImage('Default', {
title: 'Directus Docs',
});
</script>

Expand Down
69 changes: 33 additions & 36 deletions app/assets/css/main.css
Original file line number Diff line number Diff line change
@@ -1,37 +1,35 @@
@import "tailwindcss";
@import "@nuxt/ui-pro";
@import "@nuxt/ui";

@source "../../../content/**/*";


@theme static {
--font-sans: 'Inter', sans-serif;
--font-display: 'Poppins', sans-serif;

--color-purple-50: #f3f2ff;
--color-purple-100: #e9e8ff;
--color-purple-200: #d6d4ff;
--color-purple-300: #b8b1ff;
--color-purple-400: #9585ff;
--color-purple-500: #6644ff;
--color-purple-600: #6030f7;
--color-purple-700: #531ee3;
--color-purple-800: #4418bf;
--color-purple-900: #39169c;
--color-purple-950: #210b6a;
--font-sans: "Inter", sans-serif;
--font-display: "Poppins", sans-serif;

--color-purple-50: #f3f2ff;
--color-purple-100: #e9e8ff;
--color-purple-200: #d6d4ff;
--color-purple-300: #b8b1ff;
--color-purple-400: #9585ff;
--color-purple-500: #6644ff;
--color-purple-600: #6030f7;
--color-purple-700: #531ee3;
--color-purple-800: #4418bf;
--color-purple-900: #39169c;
--color-purple-950: #210b6a;

--color-pink-50: #fef1fa;
--color-pink-100: #fee5f6;
--color-pink-200: #feccee;
--color-pink-300: #ff99dd;
--color-pink-400: #fe68c9;
--color-pink-500: #f83cb0;
--color-pink-600: #e81a8f;
--color-pink-700: #ca0c72;
--color-pink-800: #a70d5e;
--color-pink-900: #8b1050;
--color-pink-950: #55022d;
--color-pink-50: #fef1fa;
--color-pink-100: #fee5f6;
--color-pink-200: #feccee;
--color-pink-300: #ff99dd;
--color-pink-400: #fe68c9;
--color-pink-500: #f83cb0;
--color-pink-600: #e81a8f;
--color-pink-700: #ca0c72;
--color-pink-800: #a70d5e;
--color-pink-900: #8b1050;
--color-pink-950: #55022d;

--diff-red: rgba(244, 63, 94, 0.2);
--diff-green: rgba(16, 185, 129, 0.2);
Expand All @@ -46,13 +44,13 @@
color utility to any element that depends on these defaults.
*/
@layer base {
*,
::after,
::before,
::backdrop,
::file-selector-button {
border-color: var(--color-gray-200, currentcolor);
}
*,
::after,
::before,
::backdrop,
::file-selector-button {
border-color: var(--color-gray-200, currentcolor);
}
}

button,
Expand All @@ -64,13 +62,12 @@ button,
cursor: default;
}


html {
scroll-behavior: smooth;
}

pre {
>code {
> code {
& .line.diff.remove {
background-color: var(--diff-red);
opacity: 0.7;
Expand Down
41 changes: 24 additions & 17 deletions app/components/CopyDocButton.vue
Original file line number Diff line number Diff line change
Expand Up @@ -20,35 +20,44 @@ const items = [
description: 'View this page as plain text',
icon: 'material-symbols:markdown-outline',
onSelect: () => {
navigateTo(`https://github.com/directus/docs/raw/refs/heads/main/content/${props.page?.stem}.md`, {
open: {
target: '_blank',
navigateTo(
`https://github.com/directus/docs/raw/refs/heads/main/content/${props.page?.stem}.md`,
{
open: {
target: '_blank',
},
},
});
);
},
},
{
label: 'Open in ChatGPT',
icon: 'i-simple-icons:openai',
target: '_blank',
onSelect() {
navigateTo(`https://chatgpt.com/?hints=search&q=${encodeURIComponent(`Read ${window.location.href} so I can ask questions about it.`)}`, {
open: {
target: '_blank',
navigateTo(
`https://chatgpt.com/?hints=search&q=${encodeURIComponent(`Read ${window.location.href} so I can ask questions about it.`)}`,
{
open: {
target: '_blank',
},
},
});
);
},
},
{
label: 'Open in Claude',
icon: 'i-simple-icons:anthropic',
target: '_blank',
onSelect() {
navigateTo(`https://claude.ai/new?q=${encodeURIComponent(`Read ${window.location.href} so I can ask questions about it.`)}`, {
open: {
target: '_blank',
navigateTo(
`https://claude.ai/new?q=${encodeURIComponent(`Read ${window.location.href} so I can ask questions about it.`)}`,
{
open: {
target: '_blank',
},
},
});
);
},
},
];
Expand All @@ -70,7 +79,7 @@ async function copyPage() {
</script>

<template>
<UButtonGroup>
<UFieldGroup>
<UButton
color="neutral"
variant="outline"
Expand Down Expand Up @@ -103,9 +112,7 @@ async function copyPage() {
</div>
</template>
</UDropdownMenu>
</UButtonGroup>
</UFieldGroup>
</template>

<style scoped>

</style>
<style scoped></style>
Original file line number Diff line number Diff line change
@@ -1,23 +1,25 @@
<script setup lang="ts">
export interface OgProps {
title: string;
title?: string;
description?: string;
breadcrumb?: string[];
}

// inherited attrs can mess up the satori parser
defineOptions({
inheritAttrs: false,
});

function truncate(str: string, n: number) {
// Leave whole words intact
function truncate(str: string | undefined, n: number) {
if (!str) return '';
const isTooLong = str.length > n;
const s = isTooLong ? str.substr(0, n - 1) : str;
const i = s.lastIndexOf(' ');
return isTooLong ? `${s.substr(0, i)}...` : s;
}

defineProps<OgProps>();
withDefaults(defineProps<OgProps>(), {
title: 'Directus Docs',
});
</script>

<template>
Expand All @@ -29,6 +31,9 @@ defineProps<OgProps>();
height: 100%;
overflow: hidden;
background-color: #000000;
background-image: url('/docs/og-image.png');
background-size: 1200px 600px;
background-repeat: no-repeat;
font-family: 'Poppins';
padding: 115px 75px 100px 75px;
"
Expand All @@ -42,15 +47,14 @@ defineProps<OgProps>();
"
>
<div
v-if="breadcrumb"
v-if="breadcrumb && breadcrumb.length"
style="display: flex; gap: 10px; margin-bottom: 20px"
>
<div
style="
color: rgba(255, 255, 255, 0.75);
font-family: 'Fira Mono';
font-size: 28px;
font-style: normal;
font-weight: 500;
line-height: 100%;
"
Expand All @@ -60,15 +64,29 @@ defineProps<OgProps>();
</div>
<h1
style="
font-family: Poppins;
font-family: 'Poppins';
color: #fff;
font-size: 84;
font-size: 84px;
line-height: 84px;
font-weight: 600;
margin: 0;
"
>
{{ truncate(title, 70) }}
</h1>
<p
v-if="description"
style="
font-family: 'Poppins';
color: rgba(255, 255, 255, 0.75);
font-size: 32px;
line-height: 44px;
font-weight: 400;
margin-top: 24px;
"
>
{{ truncate(description, 140) }}
</p>
</div>
</div>
</template>
Loading