diff --git a/.changeset/docs-accept-negotiation.md b/.changeset/docs-accept-negotiation.md new file mode 100644 index 000000000..a1e980ecd --- /dev/null +++ b/.changeset/docs-accept-negotiation.md @@ -0,0 +1,5 @@ +--- +"@tabler/docs": minor +--- + +Added `Accept: text/markdown` content negotiation for docs pages, with q-value parsing and `406` responses. diff --git a/.changeset/docs-llms-full-and-signals.md b/.changeset/docs-llms-full-and-signals.md new file mode 100644 index 000000000..edd2983b5 --- /dev/null +++ b/.changeset/docs-llms-full-and-signals.md @@ -0,0 +1,5 @@ +--- +"@tabler/docs": minor +--- + +Added a `llms-full.txt` page with all docs in one file, `Content-Signal` in robots.txt and markdown `Link` alternate headers. diff --git a/docs/astro.config.mjs b/docs/astro.config.mjs index 6fc7c9332..1ad32d365 100644 --- a/docs/astro.config.mjs +++ b/docs/astro.config.mjs @@ -6,6 +6,7 @@ import { satteri } from '@astrojs/markdown-satteri' import { unwrapJsxParagraphs } from './lib/satteri-unwrap-jsx-paragraphs.mjs' import { fileURLToPath } from 'node:url' import { copyAssets } from '../.build/copy-assets' +import { redirects } from './lib/redirects.ts' /** @param {string} p */ const path = (p) => fileURLToPath(new URL(p, import.meta.url)) @@ -30,63 +31,8 @@ export default defineConfig({ enabled: true, }, }), - // Renamed/moved pages. Add an entry here whenever a docs URL changes. - // The plural component slugs are the pre-Astro URLs still present in the - // Google index, Algolia search results and external backlinks. - redirects: { - '/ui/base/markdown': { status: 301, destination: '/ui/base/prose' }, - // @tabler/icons-eps is no longer maintained; PDF is the vector format to use. - '/icons/static-files/eps': { status: 301, destination: '/icons/static-files/pdf' }, - ...Object.fromEntries( - [ - ['alerts', 'alert'], - ['avatars', 'avatar'], - ['badges', 'badge'], - ['buttons', 'button'], - ['cards', 'card'], - ['dropdowns', 'dropdown'], - ['icons', 'icon'], - ['modals', 'modal'], - ['ribbons', 'ribbon'], - ['spinners', 'spinner'], - ['statuses', 'status'], - ['steps', 'step'], - ['tables', 'table'], - ['tabs', 'tab'], - ['timelines', 'timeline'], - ['toasts', 'toast'], - ['tooltips', 'tooltip'], - ].map(([from, to]) => [`/ui/components/${from}`, { status: 301, destination: `/ui/components/${to}` }]), - ), - // Components that need a third-party library moved to /ui/plugins/. - ...Object.fromEntries(['autosize', 'chart', 'countup', 'dropzone', 'fullcalendar', 'inline-player', 'lightbox', 'range-slider', 'signature', 'vector-map', 'wysiwyg'].map((slug) => [`/ui/components/${slug}`, { status: 301, destination: `/ui/plugins/${slug}` }])), - // Pre-Astro plural urls for two of those pages, sent straight to the new home. - '/ui/components/charts': { status: 301, destination: '/ui/plugins/chart' }, - '/ui/components/vector-maps': { status: 301, destination: '/ui/plugins/vector-map' }, - // The form- prefix was redundant inside /ui/forms/. - '/ui/forms/form-elements': { status: 301, destination: '/ui/forms/elements' }, - '/ui/forms/form-fieldset': { status: 301, destination: '/ui/forms/fieldset' }, - '/ui/forms/form-floating': { status: 301, destination: '/ui/forms/floating-labels' }, - '/ui/forms/form-helpers': { status: 301, destination: '/ui/forms/helpers' }, - '/ui/forms/form-selectboxes': { status: 301, destination: '/ui/forms/select-group' }, - '/ui/forms/form-image-check': { status: 301, destination: '/ui/forms/image-check' }, - '/ui/forms/form-color-check': { status: 301, destination: '/ui/forms/color-check' }, - '/ui/forms/form-select-tomselect': { status: 301, destination: '/ui/plugins/advanced-select' }, - '/ui/forms/form-colorpicker': { status: 301, destination: '/ui/plugins/color-picker' }, - '/ui/forms/form-datepicker': { status: 301, destination: '/ui/plugins/date-picker' }, - '/ui/forms/form-input-mask': { status: 301, destination: '/ui/plugins/input-mask' }, - '/ui/forms/form-validation': { status: 301, destination: '/ui/forms/validation' }, - // Illustrations and Emails lost their "introduction" wrapper. - '/illustrations/introduction': { status: 301, destination: '/illustrations' }, - '/illustrations/introduction/preview': { status: 301, destination: '/illustrations/preview' }, - '/illustrations/introduction/contents': { status: 301, destination: '/illustrations/contents' }, - '/illustrations/introduction/customization': { status: 301, destination: '/illustrations/customization' }, - '/illustrations/introduction/license': { status: 301, destination: '/illustrations/license' }, - '/emails/introduction': { status: 301, destination: '/emails' }, - '/emails/introduction/contents': { status: 301, destination: '/emails/contents' }, - '/emails/introduction/compiled-html': { status: 301, destination: '/emails/compiled-html' }, - '/emails/introduction/source-html': { status: 301, destination: '/emails/source-html' }, - }, + // renamed/moved pages, shared with middleware.ts + redirects, // pages live at the package root (./pages) — content-first layout; all // components/lib/data are shared (see the @shared alias). The docs content // itself lives in ./content and is rendered by pages/[...slug].astro. diff --git a/docs/layouts/DocsLayout.astro b/docs/layouts/DocsLayout.astro index 3032f0488..c67bd11b4 100644 --- a/docs/layouts/DocsLayout.astro +++ b/docs/layouts/DocsLayout.astro @@ -302,6 +302,13 @@ const relatedPages = await Promise.all(
Skip to main content + { + markdownUrl && ( + + ) + }