[docs] Simplify paths for uncategorised pages (#1619)

This PR changes the paths that we use for uncategorised pages on the
docs site.
It also redirects the old paths to the new ones.

```
// BEFORE
tldraw.dev/docs/ucg/shapes

// AFTER
tldraw.dev/docs/shapes
```

I think that this is more intuitive, and will make the links that we
share a bit clearer.
eg: As a by-product, it fixes some broken links from the introduction
page.

As a trade-off, this PR makes our pathing system a bit more complicated.
But I don't think it's tooooo bad? WDYT?

### Change Type

- [x] `documentation` — Changes to the documentation only[^2]

[^1]: publishes a `patch` release, for devDependencies use `internal`
[^2]: will not publish a new version

### Test Plan

1. Navigate to `/docs/shapes` on the docs site.
2. Make sure that it goes to the Shapes page.
3. Do the same for `/docs/ucg/shapes`


### Release Notes

- Documentation: Cleaned up some paths.
This commit is contained in:
Lu Wilson 2023-06-19 19:48:55 +01:00 committed by GitHub
parent 57bb341593
commit 8329b1da89
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 90 additions and 26 deletions

View file

@ -5,6 +5,15 @@ const nextConfig = {
scrollRestoration: true, scrollRestoration: true,
}, },
transpilePackages: ['@tldraw/utils'], transpilePackages: ['@tldraw/utils'],
async redirects() {
return [
{
source: '/:sectionId/ucg/:articleId',
destination: '/:sectionId/:articleId',
permanent: true,
},
]
},
} }
module.exports = nextConfig module.exports = nextConfig

View file

@ -18,7 +18,8 @@ import { GetStaticPaths, GetStaticProps } from 'next'
import { MDXRemoteSerializeResult } from 'next-mdx-remote' import { MDXRemoteSerializeResult } from 'next-mdx-remote'
import { useTheme } from 'next-themes' import { useTheme } from 'next-themes'
interface Props { export type ArticleProps = {
type: 'article'
sidebar: SidebarContentList sidebar: SidebarContentList
section: Section section: Section
category: Category category: Category
@ -34,7 +35,7 @@ export default function ArticlePage({
article, article,
links, links,
sidebar, sidebar,
}: Props) { }: ArticleProps) {
const theme = useTheme() const theme = useTheme()
return ( return (
<> <>
@ -55,12 +56,13 @@ export default function ArticlePage({
export const getStaticPaths: GetStaticPaths = async () => { export const getStaticPaths: GetStaticPaths = async () => {
const sections = await getSections() const sections = await getSections()
const paths: { params: { sectionId: string; categoryId: string; articleId: string } }[] = [] const paths: { params: { sectionId: string; childId: string; articleId: string } }[] = []
for (const section of sections) { for (const section of sections) {
for (const category of section.categories) { for (const category of section.categories) {
if (category.id === 'ucg') continue
for (const articleId of category.articleIds) { for (const articleId of category.articleIds) {
paths.push({ params: { sectionId: section.id, categoryId: category.id, articleId } }) paths.push({ params: { sectionId: section.id, childId: category.id, articleId } })
} }
} }
} }
@ -68,9 +70,9 @@ export const getStaticPaths: GetStaticPaths = async () => {
return { paths, fallback: false } return { paths, fallback: false }
} }
export const getStaticProps: GetStaticProps<Props> = async (ctx) => { export const getStaticProps: GetStaticProps<ArticleProps> = async (ctx) => {
const sectionId = ctx.params?.sectionId?.toString() as string const sectionId = ctx.params?.sectionId?.toString() as string
const categoryId = ctx.params?.categoryId?.toString() as string const categoryId = ctx.params?.childId?.toString() as string
const articleId = ctx.params?.articleId?.toString() const articleId = ctx.params?.articleId?.toString()
if (!articleId) throw Error() if (!articleId) throw Error()
@ -81,5 +83,15 @@ export const getStaticProps: GetStaticProps<Props> = async (ctx) => {
const links = await getLinks(articleId) const links = await getLinks(articleId)
const mdxSource = await getArticleSource(articleId) const mdxSource = await getArticleSource(articleId)
return { props: { article, section, category, sidebar, links, mdxSource } } return {
props: {
type: 'article',
article,
section,
category,
sidebar,
links,
mdxSource,
},
}
} }

View file

@ -2,11 +2,14 @@ import { Breadcrumb } from '@/components/Breadcrumb'
import { Mdx } from '@/components/Mdx' import { Mdx } from '@/components/Mdx'
import { MetaHead } from '@/components/MetaHead' import { MetaHead } from '@/components/MetaHead'
import { Sidebar } from '@/components/Sidebar' import { Sidebar } from '@/components/Sidebar'
import ArticlePage from '@/pages/[sectionId]/[childId]/[articleId]'
import { Article, Category, Section, SidebarContentList } from '@/types/content-types' import { Article, Category, Section, SidebarContentList } from '@/types/content-types'
import { import {
getArticle,
getArticleSource, getArticleSource,
getArticles, getArticles,
getCategory, getCategory,
getLinks,
getSection, getSection,
getSections, getSections,
} from '@/utils/content' } from '@/utils/content'
@ -15,8 +18,10 @@ import { GetStaticPaths, GetStaticProps } from 'next'
import { MDXRemoteSerializeResult } from 'next-mdx-remote' import { MDXRemoteSerializeResult } from 'next-mdx-remote'
import { useTheme } from 'next-themes' import { useTheme } from 'next-themes'
import Link from 'next/link' import Link from 'next/link'
import { ArticleProps } from './[articleId]'
type Props = { type CategoryProps = {
type: 'category'
sidebar: SidebarContentList sidebar: SidebarContentList
section: Section section: Section
category: Category category: Category
@ -24,15 +29,17 @@ type Props = {
mdxSource: MDXRemoteSerializeResult | null mdxSource: MDXRemoteSerializeResult | null
} }
export default function CategoryListPage({ type ChildProps = CategoryProps | ArticleProps
sidebar,
mdxSource, export default function CategoryListPage(props: ChildProps) {
articles,
section,
category,
}: Props) {
const theme = useTheme() const theme = useTheme()
if (props.type === 'article') {
return <ArticlePage {...props} />
}
const { sidebar, section, category, articles, mdxSource } = props
const ungrouped: Article[] = [] const ungrouped: Article[] = []
const groupedArticles = Object.fromEntries( const groupedArticles = Object.fromEntries(
category.groups.map((group) => [group.id, { group, articles: [] as Article[] }]) category.groups.map((group) => [group.id, { group, articles: [] as Article[] }])
@ -92,12 +99,18 @@ export default function CategoryListPage({
export const getStaticPaths: GetStaticPaths = async () => { export const getStaticPaths: GetStaticPaths = async () => {
const sections = await getSections() const sections = await getSections()
const paths: { params: { sectionId: string; categoryId: string } }[] = [] const paths: { params: { sectionId: string; childId: string } }[] = []
for (const section of sections) { for (const section of sections) {
if (section.categories) { if (section.categories) {
for (const category of section.categories) { for (const category of section.categories) {
paths.push({ params: { sectionId: section.id, categoryId: category.id } }) paths.push({ params: { sectionId: section.id, childId: category.id } })
// Add paths for uncategorized articles as well
if (category.id !== 'ucg') continue
for (const articleId of category.articleIds) {
paths.push({ params: { sectionId: section.id, childId: articleId } })
}
} }
} }
} }
@ -105,23 +118,53 @@ export const getStaticPaths: GetStaticPaths = async () => {
return { paths, fallback: false } return { paths, fallback: false }
} }
export const getStaticProps: GetStaticProps<Props> = async (ctx) => { export const getStaticProps: GetStaticProps<ChildProps> = async (ctx) => {
const sectionId = ctx.params?.sectionId?.toString() as string const sectionId = ctx.params?.sectionId?.toString() as string
const categoryId = ctx.params?.categoryId?.toString() const childId = ctx.params?.childId?.toString()
if (!categoryId || !sectionId) throw Error() if (!childId || !sectionId) throw Error()
const sidebar = await getSidebarContentList({
sectionId,
categoryId,
})
const articles = await getArticles() const articles = await getArticles()
const section = await getSection(sectionId) const section = await getSection(sectionId)
// If the path goes to an uncategorized article, show the article page
if (!section.categories.some((c) => c.id === childId)) {
const categoryId = 'ucg'
const articleId = childId
const sidebar = await getSidebarContentList({ sectionId, categoryId, articleId })
const category = await getCategory(sectionId, categoryId)
const article = await getArticle(articleId)
const links = await getLinks(articleId)
const mdxSource = await getArticleSource(articleId)
return {
props: {
type: 'article',
sidebar,
section,
category,
article,
links,
mdxSource,
},
}
}
// Otherwise, show the category page
const categoryId = childId
const sidebar = await getSidebarContentList({ sectionId, categoryId })
const category = await getCategory(sectionId, categoryId) const category = await getCategory(sectionId, categoryId)
const categoryArticles = category.articleIds.map((id) => articles[id]) const categoryArticles = category.articleIds.map((id) => articles[id])
const article = articles[categoryId + '_index'] ?? null const article = articles[categoryId + '_index'] ?? null
const mdxSource = article ? await getArticleSource(categoryId + '_index') : null const mdxSource = article ? await getArticleSource(categoryId + '_index') : null
return { props: { sidebar, section, category, articles: categoryArticles, mdxSource } } return {
props: {
type: 'category',
sidebar,
section,
category,
articles: categoryArticles,
mdxSource,
},
}
} }