1
0
Fork 0
freesewing/sites/shared/components/wrappers/mdx.mjs
joostdecock a4f192e090 fix(dev): Load MDX dynamically to reduce the number of routes
Prior to this commit we'd generate a page for each MDX document as that
avoids having to load MDX dynamically (which can be tricky) or through
static props (which causes issues with serialization).

However, Vercel (which hosts for us) has an upper limit on the number of
routes, and because of this extensive documentation, we blew passed it
with this approach.

This changes to a dynamic resolution of MDX content with an async import
in the useEffect hook. This should drastically reduce the number of
routes and make Vercel happy.

I didn't do much digging into the effects of this on SSR. If it turns
out it's causes issues, we'll deal with it at that time.
2023-05-20 13:22:36 +02:00

122 lines
4.3 KiB
JavaScript
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// Components that are available in MDX content
import { components as baseComponents } from 'shared/components/mdx/index.mjs'
// List of authors
import { authors as allAuthors } from 'config/authors.mjs'
import { docUpdates } from 'site/prebuild/doc-updates.mjs'
// Components
import { PageLink } from 'shared/components/page-link.mjs'
import { DateTime, Interval } from 'luxon'
// Context
import { useContext } from 'react'
import { NavigationContext } from 'shared/context/navigation-context.mjs'
// Hooks
import { useTranslation } from 'next-i18next'
// Previous-Next navigation
//import { PrevNext } from '../mdx/prev-next.mjs'
//
//
const TimeAgo = ({ date, t }) => {
const i = Interval.fromDateTimes(DateTime.fromISO(date), DateTime.now())
.toDuration(['hours', 'days', 'months', 'years'])
.toObject()
let ago = ''
if (i.years < 1 && i.months < 1) {
if (Math.floor(i.days) === 1) ago += `${t('oneDay')}`
else if (Math.floor(i.days) === 0) ago += `${t('lessThanADay')}`
} else {
if (i.years === 1) ago += `${i.years} ${t('year')}, `
else if (i.years > 1) ago += `${i.years} ${t('years')}, `
if (i.months === 1) ago += `${i.months} ${t('month')}`
else if (i.months > 1) ago += `${i.months} ${t('months')}`
}
return `${ago} ${t('ago')}`
}
const PersonList = ({ list }) =>
list.map((id, i) => (
<li key={id} className="list-none">
{allAuthors[id] ? (
<PageLink href={`/users/${allAuthors[id].id}`} txt={allAuthors[id].name} />
) : (
<span className="font-medium">{id}</span>
)}
{i !== list.length - 1 ? ',' : <span className="pl-2 pr-1 font-bold">|</span>}
</li>
))
const Ul = ({ children }) => (
<ul key="authors" className="flex flex-row flex-wrap gap-1 -ml-3">
{children}
</ul>
)
const MetaData = ({ authors = [], maintainers = [], updated = '20220825', locale, slug, t }) => (
<div className="py-4 px-4 rounded-lg bg-secondary bg-opacity-10 shadow mb-4">
{locale === 'en' ? (
<div className="flex flex-row items-center gap-4 justify-between text-base-content mb-2">
<span className="font-medium text-lg">{t('helpImproveDocs')}</span>
<a
href={`https://github.dev/freesewing/freesewing/blob/develop/markdown/org/${slug}/en.md`}
className="btn btn-secondary btn-sm flex flex-row gap-2 items-center"
>
<span role="img"></span>
<span className="text-secondary-content">{t('editThisPage')}</span>
</a>
</div>
) : (
<div className="flex flex-row items-center gap-4 justify-between text-base-content mb-2">
<span className="font-medium text-lg">{t('helpTranslateDocs')}</span>
<a
href={`https://freesewing.dev/guides/translation`}
className="btn btn-secondary btn-sm flex flex-row gap-2 items-center"
>
<span role="img">💡</span>
<span className="text-secondary-content">{t('learnMore')}</span>
</a>
</div>
)}
<div className="p-2 text-sm">
<Ul>
{authors.length > 0 ? (
<>
<li className="list-none font-medium opacity-70 italic">{t('authors')}:</li>
<PersonList list={authors} slug={slug} />
</>
) : null}
{maintainers.length > 0 ? (
<>
<li className="list-none font-medium opacity-70 italic">{t('maintainers')}:</li>
<PersonList list={authors} />
</>
) : null}
<li className="list-none font-medium opacity-70 italic">{t('lastUpdated')}:</li>
<li className="list-none font-medium">
<TimeAgo date={updated} t={t} />
</li>
</Ul>
</div>
</div>
)
export const MdxWrapper = ({ MDX = false, frontmatter = {}, components = {}, children = [] }) => {
const { t } = useTranslation('docs')
const allComponents = { ...baseComponents, ...components }
const { locale, slug } = useContext(NavigationContext)
const updates = docUpdates[slug] || {}
return (
<div className="text-primary mdx max-w-prose text-base-content max-w-prose text-base">
<MetaData
maintainers={frontmatter?.maintainers || []}
authors={updates.authors || []}
lastUpdated={updates.lastUpdates}
{...{ locale, slug, t }}
/>
{MDX ? <MDX components={allComponents} /> : children}
</div>
)
}