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
Original file line number Diff line number Diff line change
Expand Up @@ -684,6 +684,7 @@ export const PhoneLoginsItems = [
export const auth: NavMenuConstant = {
icon: 'auth',
title: 'Auth',
url: '/guides/auth',
items: [
{
name: 'Overview',
Expand Down
6 changes: 2 additions & 4 deletions apps/docs/features/docs/GuidesMdx.template.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -71,10 +71,8 @@ const GuideTemplate = ({
}: GuideTemplateProps) => {
const hideToc = meta?.hideToc || meta?.hide_table_of_contents
const breadcrumbChain = resolveBreadcrumbs(pathname)
const breadcrumbJsonLd =
breadcrumbChain.length > 0
? serializeJsonLd(breadcrumbListSchema({ pathname, chain: breadcrumbChain }))
: null
const breadcrumbSchema = breadcrumbListSchema({ pathname, chain: breadcrumbChain })
const breadcrumbJsonLd = breadcrumbSchema ? serializeJsonLd(breadcrumbSchema) : null

return (
<TocAnchorsProvider>
Expand Down
59 changes: 59 additions & 0 deletions apps/docs/lib/json-ld.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'

import { breadcrumbListSchema } from './json-ld'

describe('breadcrumbListSchema', () => {
let warn: ReturnType<typeof vi.spyOn>

beforeEach(() => {
warn = vi.spyOn(console, 'warn').mockImplementation(() => {})
})

afterEach(() => {
warn.mockRestore()
})

it('emits item and name on every position when all chain items have urls', () => {
const result = breadcrumbListSchema({
pathname: '/guides/auth/jwts',
chain: [
{ name: 'Authentication', url: '/guides/auth' },
{ name: 'JWTs', url: '/guides/auth/jwts' },
],
})

expect(result).not.toBeNull()
expect(result!.itemListElement).toHaveLength(4)
for (const entry of result!.itemListElement) {
expect(typeof entry.item).toBe('string')
expect(entry.item).toMatch(/^https?:\/\//)
expect(typeof entry.name).toBe('string')
}
})

it('uses pathname for the leaf url even when chain leaf url differs', () => {
const result = breadcrumbListSchema({
pathname: '/guides/database/postgres-js',
chain: [{ name: 'Postgres.js', url: '/guides/database/postgres-js-old' }],
})

expect(result).not.toBeNull()
const leaf = result!.itemListElement.at(-1)
expect(leaf?.item).toMatch(/\/guides\/database\/postgres-js$/)
})

it('returns null when every chain item is url-less', () => {
const result = breadcrumbListSchema({
pathname: '/guides/some-broken-route',
chain: [{ name: 'Category A' }, { name: 'Category B' }],
})

expect(result).toBeNull()
})

it('returns null on an empty chain', () => {
const result = breadcrumbListSchema({ pathname: '/guides', chain: [] })

expect(result).toBeNull()
})
})
43 changes: 33 additions & 10 deletions apps/docs/lib/json-ld.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,31 +10,54 @@ export function serializeJsonLd(schema: JsonLdSchema): string {
.replace(/&/g, '\\u0026')
}

const DOCS_ROOT: BreadcrumbItem = { name: 'Docs', url: '' }
const GUIDES_ROOT: BreadcrumbItem = { name: 'Guides', url: '/guides' }
type ValidCrumb = BreadcrumbItem & { url: string }

const DOCS_ROOT: ValidCrumb = { name: 'Docs', url: '' }
const GUIDES_ROOT: ValidCrumb = { name: 'Guides', url: '/guides' }

interface BreadcrumbListSchemaInput {
pathname: string
chain: BreadcrumbItem[]
}

const warnedPaths = new Set<string>()

function isValidCrumb(crumb: BreadcrumbItem): crumb is ValidCrumb {
return crumb.url !== undefined && Boolean(crumb.title ?? crumb.name)
}

export function breadcrumbListSchema({ pathname, chain }: BreadcrumbListSchemaInput) {
const fullChain: BreadcrumbItem[] = [DOCS_ROOT, GUIDES_ROOT, ...chain]
const filteredChain = chain.filter(isValidCrumb)

if (
process.env.NODE_ENV !== 'production' &&
filteredChain.length !== chain.length &&
!warnedPaths.has(pathname)
) {
warnedPaths.add(pathname)
const dropped = chain
.filter((crumb) => !isValidCrumb(crumb))
.map((crumb) => crumb.title ?? crumb.name ?? '<unnamed>')
console.warn(
`[json-ld] Dropping breadcrumb items missing url or name from ${pathname}: ${dropped.join(', ')}`
)
}

if (filteredChain.length === 0) return null

const fullChain: ValidCrumb[] = [DOCS_ROOT, GUIDES_ROOT, ...filteredChain]

const itemListElement = fullChain.map((crumb, index) => {
const isLeaf = index === fullChain.length - 1
const name = crumb.title ?? crumb.name
const path = isLeaf ? pathname : crumb.url
const itemUrl = path === '' ? PROD_URL : `${PROD_URL}${path}`

const listItem: Record<string, unknown> = {
return {
'@type': 'ListItem',
position: index + 1,
name,
}
if (path !== undefined) {
listItem.item = path === '' ? PROD_URL : `${PROD_URL}${path}`
name: crumb.title ?? crumb.name,
item: itemUrl,
}
return listItem
})

return {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ export const GITHUB_ICON = (
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 98 96" className="w-5 shrink-0">
<title>GitHub icon</title>
<path
fill="#ffffff"
fill="currentColor"
fillRule="evenodd"
d="M48.854 0C21.839 0 0 22 0 49.217c0 21.756 13.993 40.172 33.405 46.69 2.427.49 3.316-1.059 3.316-2.362 0-1.141-.08-5.052-.08-9.127-13.59 2.934-16.42-5.867-16.42-5.867-2.184-5.704-5.42-7.17-5.42-7.17-4.448-3.015.324-3.015.324-3.015 4.934.326 7.523 5.052 7.523 5.052 4.367 7.496 11.404 5.378 14.235 4.074.404-3.178 1.699-5.378 3.074-6.6-10.839-1.141-22.243-5.378-22.243-24.283 0-5.378 1.94-9.778 5.014-13.2-.485-1.222-2.184-6.275.486-13.038 0 0 4.125-1.304 13.426 5.052a46.97 46.97 0 0 1 12.214-1.63c4.125 0 8.33.571 12.213 1.63 9.302-6.356 13.427-5.052 13.427-5.052 2.67 6.763.97 11.816.485 13.038 3.155 3.422 5.015 7.822 5.015 13.2 0 18.905-11.404 23.06-22.324 24.283 1.78 1.548 3.316 4.481 3.316 9.126 0 6.6-.08 11.897-.08 13.526 0 1.304.89 2.853 3.316 2.364 19.412-6.52 33.405-24.935 33.405-46.691C97.707 22 75.788 0 48.854 0z"
clipRule="evenodd"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
import { MoreHorizontal } from 'lucide-react'
import Link from 'next/link'
import { type MouseEventHandler } from 'react'
import { Button, cn, DropdownMenu, DropdownMenuContent, DropdownMenuTrigger } from 'ui'

type Props = {
label: string
icon: React.ReactNode
icon?: React.ReactNode
dropdownItems?: React.ReactNode
href: string
isActive: boolean
onClick?: (e: any) => void
onClick?: MouseEventHandler<HTMLAnchorElement>
}
export function LogsSidebarItem({ label, icon, dropdownItems, href, isActive, onClick }: Props) {
return (
Expand All @@ -25,7 +26,7 @@ export function LogsSidebarItem({ label, icon, dropdownItems, href, isActive, on
href={href}
className={'h-7 flex-1 text-sm px-4 flex items-center gap-2 truncate'}
>
<span>{icon}</span>
{icon && <span>{icon}</span>}
<span className="truncate">{label}</span>
</Link>
{dropdownItems && (
Expand Down
19 changes: 0 additions & 19 deletions apps/studio/components/layouts/LogsLayout/LogsSidebarMenuV2.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,23 +35,6 @@ import { useReplicationSourcesQuery } from '@/data/replication/sources-query'
import { useCheckEntitlements } from '@/hooks/misc/useCheckEntitlements'
import { useIsFeatureEnabled } from '@/hooks/misc/useIsFeatureEnabled'

const SupaIcon = ({ className }: { className?: string }) => {
return (
<svg
stroke="currentColor"
fill="currentColor"
strokeWidth="0"
viewBox="0 0 24 24"
height="15px"
width="15px"
className={className}
xmlns="http://www.w3.org/2000/svg"
>
<path d="M10.9997 2.59833V13.9694H3.90013C3.23055 13.9694 2.83063 13.1846 3.25654 12.6326L10.9997 2.59833ZM12.9997 8.03061V2.33296C12.9997 0.521514 10.7034 -0.291434 9.58194 1.16185L1.67316 11.4108C0.246185 13.26 1.54768 15.9694 3.90013 15.9694H10.9997V21.6671C10.9997 23.4785 13.296 24.2915 14.4175 22.8382L22.3262 12.5892C23.7532 10.74 22.4517 8.03061 20.0993 8.03061H12.9997ZM12.9997 10.0306H20.0993C20.7688 10.0306 21.1688 10.8155 20.7429 11.3674L12.9997 21.4017V10.0306Z"></path>
</svg>
)
}

export function SidebarCollapsible({
children,
title,
Expand Down Expand Up @@ -323,7 +306,6 @@ export function LogsSidebarMenuV2() {
key={collection?.key ?? ''}
isActive={isItemActive}
href={collection?.url ?? ''}
icon={<SupaIcon className="text-foreground-light" />}
label={collection?.name ?? ''}
/>
)
Expand All @@ -338,7 +320,6 @@ export function LogsSidebarMenuV2() {
key={collection.key}
isActive={isActive(collection.url)}
href={collection.url}
icon={<SupaIcon className="text-foreground-light" />}
label={collection.name}
/>
))}
Expand Down
3 changes: 2 additions & 1 deletion apps/www/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ public/sitemap_www.xml
# Generated .md content bundle (built by scripts/generateMdContent.mjs)
app/api-v2/md/content.generated.ts

# Changelog generated feeds and markdown (built by content:build)
# Generated feeds and markdown (built by content:build)
/public/rss.xml
/public/changelog-rss.xml
/public/changelog-rss
/public/changelog.md
Expand Down
8 changes: 4 additions & 4 deletions apps/www/internals/generate-sitemap.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,11 @@ async function generate() {
'pages/*.tsx',
'pages/*.mdx',
'pages/**/*.tsx',
'data/**/*.mdx',
'_blog/*.mdx',
'_case-studies/*.mdx',
'_customers/*.mdx',
'_events/*.mdx',
'_alternatives/*.mdx',
'!data/*.mdx',
'!pages/_*.js',
'!pages/_*.tsx',
'!pages/api',
Expand All @@ -38,7 +36,7 @@ async function generate() {
.map((page) => {
const path = page
.replace('.next/server/pages', '')
.replace('pages', '')
.replace(/^pages/, '')
.replace('.html', '')
// add a `/` for blog posts
.replace('_blog', `/${blogUrl}`)
Expand Down Expand Up @@ -120,7 +118,9 @@ async function generate() {
const changelogDetailUrls = (() => {
try {
const rss = readFileSync('public/changelog-rss.xml', 'utf-8')
const matches = [...rss.matchAll(/<link>(https:\/\/supabase\.com\/changelog\/\d+[^<]*)<\/link>/g)]
const matches = [
...rss.matchAll(/<link>(https:\/\/supabase\.com\/changelog\/\d+[^<]*)<\/link>/g),
]
const uniqueUrls = [...new Set(matches.map((match) => match[1]))]

return uniqueUrls.map(
Expand Down
Loading
Loading