Files
supabase/apps/docs/next.config.mjs
Danny White 59e2122833 docs(pipelines): nest destination guides (#50708)
## Problem

Pipeline destination guides live beside the Pipelines overview, so their
sidebar hierarchy and URLs do not reflect that they belong to Pipelines.

## Solution

Moves the BigQuery, ClickHouse, DuckLake, and Snowflake guides under
`/database/replication/pipelines/`, redirects the old URLs in both docs
preview (`apps/docs/next.config.mjs`) and production
(`apps/www/lib/redirects.js`), and updates internal documentation links.

The matching Studio changes, including destination-aware links from the
creation sheet, will follow in a separate PR.

## To test

- [Pipelines
overview](https://docs-git-dnywh-docsnest-pipeline-destinations-supabase.vercel.app/docs/guides/database/replication/pipelines)
- Destination guides:
[BigQuery](https://docs-git-dnywh-docsnest-pipeline-destinations-supabase.vercel.app/docs/guides/database/replication/pipelines/bigquery),
[ClickHouse](https://docs-git-dnywh-docsnest-pipeline-destinations-supabase.vercel.app/docs/guides/database/replication/pipelines/clickhouse),
[DuckLake](https://docs-git-dnywh-docsnest-pipeline-destinations-supabase.vercel.app/docs/guides/database/replication/pipelines/ducklake),
[Snowflake](https://docs-git-dnywh-docsnest-pipeline-destinations-supabase.vercel.app/docs/guides/database/replication/pipelines/snowflake)
- [Old Snowflake
URL](https://docs-git-dnywh-docsnest-pipeline-destinations-supabase.vercel.app/docs/guides/database/replication/snowflake)

## Review instructions

1. Open the Pipelines overview and confirm the four destination guides
appear beneath Pipelines in the sidebar.
2. Open each destination guide and confirm its nested URL and content
load correctly.
3. Open the old Snowflake URL and confirm it redirects to its new
location.

## Checklist

- [x] I have read
[CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md)
- [x] If I wrote a new docs topic or edited an existing topic, I used
the `/write-the-docs` or `/edit-the-docs` skill, which references
[WORD_LIST](https://github.com/supabase/supabase/blob/master/apps/docs/WORD_LIST.md)
and the docs
[CONTRIBUTING](https://github.com/supabase/supabase/blob/master/apps/docs/CONTRIBUTING.md)
guide

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Documentation**
* Moved BigQuery, ClickHouse, DuckLake, and Snowflake replication guides
to a dedicated pipelines section and updated related navigation and
links.
* **Bug Fixes**
* Added permanent redirects so existing links to the four destination
guides continue to work.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-09-23 10:53:50 +10:00

293 lines
8.3 KiB
JavaScript

// @ts-check
import configureBundleAnalyzer from '@next/bundle-analyzer'
import nextMdx from '@next/mdx'
import { withSentryConfig } from '@sentry/nextjs'
import withYaml from 'next-plugin-yaml'
import rehypeSlug from 'rehype-slug'
import remarkGfm from 'remark-gfm'
import { parse as parseToml } from 'smol-toml'
import remotePatterns from './lib/remotePatterns.js'
const withBundleAnalyzer = configureBundleAnalyzer({
enabled: process.env.ANALYZE === 'true',
})
const withMDX = nextMdx({
extension: /\.mdx?$/,
options: {
remarkPlugins: [remarkGfm],
rehypePlugins: [rehypeSlug],
providerImportSource: '@mdx-js/react',
},
})
/** @type {import('next').NextConfig} nextConfig */
const nextConfig = {
assetPrefix: getAssetPrefix(),
// Append the default value with md extensions
pageExtensions: ['ts', 'tsx', 'js', 'jsx', 'md', 'mdx'],
// reactStrictMode: true,
// swcMinify: true,
basePath: process.env.NEXT_PUBLIC_BASE_PATH || '/docs',
images: {
dangerouslyAllowSVG: false,
// @ts-ignore
remotePatterns,
},
webpack: (config) => {
config.module.rules.push({
test: /\.include$/,
type: 'asset/source',
})
config.module.rules.push({
test: /\.toml$/,
type: 'json',
parser: {
parse: parseToml,
},
})
return config
},
transpilePackages: [
'ui',
'ui-patterns',
'common',
'dayjs',
'shared-data',
'api-types',
'icons',
'next-mdx-remote',
],
outputFileTracingIncludes: {
'/api/crawlers': ['./features/docs/generated/**/*', './docs/ref/**/*'],
'/api/guides-md/**/*': ['./public/markdown/guides/**/*'],
'/guides/**/*': ['./content/guides/**/*', './content/troubleshooting/**/*', './examples/**/*'],
'/reference/**/*': ['./features/docs/generated/**/*', './docs/ref/**/*'],
},
serverExternalPackages: ['libpg-query', 'twoslash'],
async headers() {
return [
{
source: '/:path*',
headers: [
{
key: 'Strict-Transport-Security',
value: process.env.VERCEL === '1' ? 'max-age=31536000; includeSubDomains; preload' : '',
},
{
key: 'X-Robots-Tag',
value: 'all',
},
{
key: 'X-Frame-Options',
value: 'DENY',
},
],
has: [
{
type: 'host',
value: 'supabase.com',
},
],
},
{
source: '/:path*',
headers: [
{
key: 'Strict-Transport-Security',
value: process.env.VERCEL === '1' ? 'max-age=31536000; includeSubDomains; preload' : '',
},
{
key: 'X-Robots-Tag',
value: 'noindex',
},
{
key: 'X-Frame-Options',
value: 'DENY',
},
],
has: [
{
type: 'host',
value: '(?:.+\\.vercel\\.app)',
},
],
},
{
source: '/favicon/:slug*',
headers: [{ key: 'cache-control', value: 'public, max-age=86400' }],
},
]
},
/**
* Doc rewrites and redirects are
* handled by the `www` nextjs config:
*
* ./apps/www/lib/redirects.js
*
* Only add dev/preview specific redirects
* in this config.
*/
async redirects() {
return [
{
source: '/guides/observability/access-data',
destination: '/guides/observability',
permanent: true,
},
{
source: '/guides/observability/access-data.md',
destination: '/guides/observability.md',
permanent: true,
},
// Redirect root to docs base path in dev/preview envs
{
source: '/',
destination: '/docs',
basePath: false,
permanent: false,
},
// Redirect dashboard links in dev/preview envs
{
source: '/dashboard/:path*',
destination: 'https://supabase.com/dashboard/:path*',
basePath: false,
permanent: false,
},
// Redirect blog links in dev/preview envs
{
source: '/blog/:path*',
destination: 'https://supabase.com/blog/:path*',
basePath: false,
permanent: false,
},
// Redirect old managed pipeline slugs in dev/preview envs
{
source: '/guides/database/replication/bigquery',
destination: '/guides/database/replication/pipelines/bigquery',
permanent: true,
},
{
source: '/guides/database/replication/clickhouse',
destination: '/guides/database/replication/pipelines/clickhouse',
permanent: true,
},
{
source: '/guides/database/replication/ducklake',
destination: '/guides/database/replication/pipelines/ducklake',
permanent: true,
},
{
source: '/guides/database/replication/snowflake',
destination: '/guides/database/replication/pipelines/snowflake',
permanent: true,
},
{
source: '/guides/database/replication/external-replication-setup',
destination: '/guides/database/replication/pipelines',
permanent: true,
},
{
source: '/guides/database/replication/external-replication-monitoring',
destination: '/guides/database/replication/pipelines-monitoring',
permanent: true,
},
{
source: '/guides/database/replication/external-replication-faq',
destination: '/guides/database/replication/pipelines-faq',
permanent: true,
},
{
source: '/guides/database/replication/replication-setup',
destination: '/guides/database/replication/pipelines',
permanent: true,
},
{
source: '/guides/database/replication/replication-monitoring',
destination: '/guides/database/replication/pipelines-monitoring',
permanent: true,
},
{
source: '/guides/database/replication/replication-faq',
destination: '/guides/database/replication/pipelines-faq',
permanent: true,
},
{
source: '/guides/database/inspect',
destination: '/guides/monitoring-and-debugging/inspect',
permanent: true,
},
{
source: '/guides/database/database-advisors',
destination: '/guides/observability/advisors',
permanent: true,
},
]
},
typescript: {
// On previews, typechecking is run via GitHub Action only for efficiency
// On production, we turn it on to prevent errors from conflicting PRs getting into
// prod
ignoreBuildErrors: process.env.NEXT_PUBLIC_VERCEL_ENV === 'production' ? false : true,
},
eslint: {
// We are already running linting via GH action, this will skip linting during production build on Vercel
ignoreDuringBuilds: true,
},
}
const configExport = () => {
const plugins = [withMDX, withYaml, withBundleAnalyzer]
// @ts-ignore
return plugins.reduce((acc, next) => next(acc), nextConfig)
}
export default withSentryConfig(configExport, {
// For all available options, see:
// https://www.npmjs.com/package/@sentry/webpack-plugin#options
org: 'supabase',
project: 'docs',
unstable_sentryWebpackPluginOptions: {
applicationKey: 'supabase-docs',
},
// Only print logs for uploading source maps in CI
silent: !process.env.CI,
// For all available options, see:
// https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup/
// Upload a larger set of source maps for prettier stack traces (increases build time)
widenClientFileUpload: true,
// Uncomment to route browser requests to Sentry through a Next.js rewrite to circumvent ad-blockers.
// This can increase your server load as well as your hosting bill.
// Note: Check that the configured route will not match with your Next.js middleware, otherwise reporting of client-
// side errors will fail.
// tunnelRoute: "/monitoring",
// Automatically tree-shake Sentry logger statements to reduce bundle size
disableLogger: true,
})
function getAssetPrefix() {
// If not force enabled, but not production env, disable CDN
if (process.env.FORCE_ASSET_CDN !== '1' && process.env.VERCEL_ENV !== 'production') {
return undefined
}
// Force disable CDN
if (process.env.FORCE_ASSET_CDN === '-1') {
return undefined
}
// @ts-ignore
return `https://frontend-assets.supabase.com/${process.env.SITE_NAME}/${process.env.VERCEL_GIT_COMMIT_SHA.substring(0, 12)}`
}