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
16 changes: 2 additions & 14 deletions apps/docs/app/sitemap.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { MetadataRoute } from 'next'
import { db } from '@/utils/ContentDatabase'
import { fetchFramerPaths } from '@/utils/framer-sitemap'

export default async function sitemap(): Promise<MetadataRoute.Sitemap> {
const paths = await db.getAllPaths()

// Docs-only sitemap. Marketing pages are now owned by the dotdev app.
const docsSitemap: MetadataRoute.Sitemap = [
{
url: 'https://tldraw.dev/',
Expand All @@ -15,17 +15,5 @@ export default async function sitemap(): Promise<MetadataRoute.Sitemap> {
lastModified: new Date(),
})),
]

const framerPaths = await fetchFramerPaths()
const docsPaths = new Set(paths.map((p: string) => p.toLowerCase()))
const framerSitemap: MetadataRoute.Sitemap = []

for (const path of framerPaths) {
// Filter out root path and any paths that conflict with docs routes
if (path === '/') continue
if (docsPaths.has(path.toLowerCase())) continue
framerSitemap.push({ url: 'https://tldraw.dev' + path })
}

return [...docsSitemap, ...framerSitemap]
return docsSitemap
}
103 changes: 2 additions & 101 deletions apps/docs/next.config.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
/** @type {import('next').NextConfig} */

// Configurable domain for rewrites
const REWRITE_DOMAIN = 'tldrawdotdev.framer.website'

/** Keep in sync with `utils/asset-url.ts` (`resolveAssetOrigin`). */
function resolveAssetOrigin() {
const explicit =
process.env.ASSET_PREFIX?.trim() ||
Expand Down Expand Up @@ -212,104 +208,9 @@ const nextConfig = {
]
},
async rewrites() {
const rewrites = {
beforeFiles: [
{
source: '/',
destination: `https://${REWRITE_DOMAIN}/`,
},
{
source: '/404',
destination: `https://${REWRITE_DOMAIN}/404`,
},
{
source: '/accessibility',
destination: `https://${REWRITE_DOMAIN}/accessibility`,
},
{
source: '/blog/announcements',
destination: `https://${REWRITE_DOMAIN}/blog/category/announcements`,
},
{
source: '/blog/case-studies',
destination: `https://${REWRITE_DOMAIN}/blog/category/case-studies`,
},
{
source: '/blog/product',
destination: `https://${REWRITE_DOMAIN}/blog/category/product`,
},
{
source: '/blog/release-notes',
destination: `https://${REWRITE_DOMAIN}/blog/category/release-notes`,
},
{
source: '/blog',
destination: `https://${REWRITE_DOMAIN}/blog`,
},
{
source: '/blog/:path+',
destination: `https://${REWRITE_DOMAIN}/blog/:path*`,
},
{
source: '/careers',
destination: `https://${REWRITE_DOMAIN}/careers`,
},
{
source: '/company',
destination: `https://${REWRITE_DOMAIN}/company`,
},
{
source: '/events',
destination: `https://${REWRITE_DOMAIN}/events`,
},
{
source: '/faq',
destination: `https://${REWRITE_DOMAIN}/faq`,
},
{
source: '/features/:path*',
destination: `https://${REWRITE_DOMAIN}/features/:path*`,
},
{
source: '/get-a-license/:path*',
destination: `https://${REWRITE_DOMAIN}/get-a-license/:path*`,
},
{
source: '/legal/:path*',
destination: `https://${REWRITE_DOMAIN}/legal/:path*`,
},
{
source: '/partner',
destination: `https://${REWRITE_DOMAIN}/partner`,
},
{
source: '/pricing',
destination: `https://${REWRITE_DOMAIN}/pricing`,
},
{
source: '/showcase',
destination: `https://${REWRITE_DOMAIN}/showcase`,
},
{
source: '/thanks',
destination: `https://${REWRITE_DOMAIN}/thanks`,
},
{
source: '/releases',
destination: '/getting-started/releases',
},
{
source: '/quick-start',
destination: '/getting-started/quick-start',
},
{
source: '/installation',
destination: '/getting-started/installation',
},
],
return {
beforeFiles: [],
}

return rewrites
},
}

Expand Down
36 changes: 30 additions & 6 deletions apps/docs/scripts/lib/checkBrokenLinks.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { fetchFramerPaths } from '@/utils/framer-sitemap'
import { nicelog } from '@/utils/nicelog'
import { connect } from './connect'

Expand All @@ -16,6 +15,32 @@ const INTERNAL_REWRITES: Record<string, string> = {
'/installation': '/getting-started/installation',
}

// Path prefixes that are served by another system (e.g. the marketing site)
// rather than this Next.js app, so they will never appear in the docs DB.
// Matches the prefix as an exact path OR as a parent of a subpath:
// e.g. '/legal' matches '/legal' and '/legal/tldraw-license' but not '/legal-foo'.
const EXTERNAL_ROUTE_PREFIXES = [
'/accessibility',
'/blog',
'/careers',
'/company',
'/events',
'/faq',
'/features',
'/get-a-license',
'/legal',
'/partner',
'/pricing',
'/showcase',
'/thanks',
]

function isExternalRoute(urlPath: string): boolean {
return EXTERNAL_ROUTE_PREFIXES.some(
(prefix) => urlPath === prefix || urlPath.startsWith(prefix + '/')
)
}

/**
* Strip fenced code blocks from markdown, replacing them with blank lines
* to preserve line numbering for error reporting.
Expand Down Expand Up @@ -109,9 +134,6 @@ function tryRedirect(urlPath: string): string | null {
export async function checkBrokenLinks(): Promise<number> {
const db = await connect({ mode: 'readonly' })

// Fetch framer paths from the live sitemap so we don't maintain a stale list
const framerPaths = await fetchFramerPaths()

// Build set of all valid paths
const validPaths = new Set<string>()

Expand Down Expand Up @@ -198,6 +220,10 @@ export async function checkBrokenLinks(): Promise<number> {
const urlPath = hashIdx >= 0 ? url.slice(0, hashIdx) : url
const fragment = hashIdx >= 0 ? url.slice(hashIdx + 1).toLowerCase() : null

// Skip paths served by an external system (marketing site etc.)
// — they will never appear in the docs DB but are still valid in production.
if (isExternalRoute(urlPath)) continue

// Empty path with fragment = same-page anchor
if (urlPath === '' && fragment) {
const slugs = headingMap.get(article.path)
Expand All @@ -222,8 +248,6 @@ export async function checkBrokenLinks(): Promise<number> {
// Case-insensitive fallback (handles macOS FS collisions
// where e.g. Atom.mdx and atom.mdx map to the same file)
pathValid = true
} else if (framerPaths.has(urlPath)) {
pathValid = true
} else {
// Try redirect resolution
const redirected = tryRedirect(urlPath)
Expand Down
30 changes: 0 additions & 30 deletions apps/docs/utils/framer-sitemap.ts

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@ ZERO_CVR_MAX_CONNS = "__RM_CVR_MAX_CONNS"
ZERO_CHANGE_MAX_CONNS = "__RM_CHANGE_MAX_CONNS"
ZERO_LITESTREAM_BACKUP_URL = "s3://__ZERO_R2_BUCKET_NAME/__BACKUP_PATH"
ZERO_LITESTREAM_ENDPOINT = "__ZERO_R2_ENDPOINT"
ZERO_LOG_LEVEL = "info"
ZERO_LOG_LEVEL = "warn"
OTEL_TRACES_EXPORTER = "none"
DO_NOT_TRACK = "1"
OTEL_NODE_RESOURCE_DETECTORS = "env,host,os"
OTEL_RESOURCE_ATTRIBUTES = "service.name=zero-rm,service.namespace=dotcom,deployment.environment=__TLDRAW_ENV,service.version=__ZERO_VERSION"
3 changes: 2 additions & 1 deletion apps/dotcom/zero-cache/flyio-view-syncer.template.toml
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,8 @@ ZERO_ENABLE_CRUD_MUTATIONS = "false"
ZERO_UPSTREAM_MAX_CONNS = "__VS_UPSTREAM_MAX_CONNS"
ZERO_CVR_MAX_CONNS = "__VS_CVR_MAX_CONNS"
ZERO_CHANGE_MAX_CONNS = "__VS_CHANGE_MAX_CONNS"
ZERO_LOG_LEVEL = "info"
ZERO_LOG_LEVEL = "warn"
OTEL_TRACES_EXPORTER = "none"
DO_NOT_TRACK = "1"
OTEL_NODE_RESOURCE_DETECTORS = "env,host,os"
OTEL_RESOURCE_ATTRIBUTES = "service.name=zero-vs,service.namespace=dotcom,deployment.environment=__TLDRAW_ENV,service.version=__ZERO_VERSION"
Expand Down
3 changes: 2 additions & 1 deletion apps/dotcom/zero-cache/flyio.template.toml
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@ ZERO_ADMIN_PASSWORD = "__ZERO_ADMIN_PASSWORD"
ZERO_UPSTREAM_MAX_CONNS = "__SINGLE_UPSTREAM_MAX_CONNS"
ZERO_CVR_MAX_CONNS = "__SINGLE_CVR_MAX_CONNS"
ZERO_CHANGE_MAX_CONNS = "__SINGLE_CHANGE_MAX_CONNS"
ZERO_LOG_LEVEL = "info"
ZERO_LOG_LEVEL = "warn"
OTEL_TRACES_EXPORTER = "none"
ZERO_MUTATE_URL = "__ZERO_MUTATE_URL"
ZERO_QUERY_URL = "__ZERO_QUERY_URL"
ZERO_ENABLE_CRUD_MUTATIONS = "false"
Expand Down
11 changes: 11 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,17 @@
"our examples app depenends on pdf.js which pulls in canvas as an optional dependency.",
"it slows down installs quite a bit though, so we replace it with an empty package."
],
"// dependenciesMeta.workerd": [
"workerd's postinstall script runs the native binary to self-check it, which fails on",
"CI images without GLIBC 2.35+ (e.g. Vercel, which builds the docs site). Skipping the",
"build script doesn't affect wrangler at dev time — wrangler still invokes the platform",
"binary normally on developer machines."
],
"dependenciesMeta": {
"workerd": {
"built": false
}
},
"resolutions": {
"domino@^2.1.6": "patch:domino@npm%3A2.1.6#./.yarn/patches/domino-npm-2.1.6-b0dc3de857.patch",
"canvas": "npm:empty-npm-package@1.0.0",
Expand Down
3 changes: 3 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -12045,6 +12045,9 @@ __metadata:
vite-plugin-circular-dependency: "npm:^0.5.0"
vitest: "npm:^3.2.4"
vitest-canvas-mock: "npm:^1.1.3"
dependenciesMeta:
workerd:
built: false
languageName: unknown
linkType: soft

Expand Down
Loading