Last active
March 20, 2023 19:27
-
-
Save davestewart/7fbd3396d3b8743f9cfa48f5b83d9cfd to your computer and use it in GitHub Desktop.
Auto indexing for Nuxt 3 Content
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// modules/content-indexer.ts | |
import Fs from 'fs' | |
import Path from 'path' | |
import { defineNuxtModule, extendPages, extendRouteRules } from '@nuxt/kit' | |
import { ModuleOptions, Nuxt } from '@nuxt/schema' | |
import { MountOptions } from '@nuxt/content' | |
const name = 'content-indexer' | |
export default defineNuxtModule({ | |
meta: { | |
name, | |
}, | |
setup (options: ModuleOptions, nuxt: Nuxt) { | |
// config | |
const { srcDir, debug } = nuxt.options | |
const config = nuxt.options.content | |
const sources = config?.sources | |
// target dirs | |
const dirs = [ | |
srcDir + '/content', | |
] | |
// additional sources | |
if (sources) { | |
// helper | |
const addSource = (source: MountOptions) => { | |
if (source.driver === 'fs') { | |
dirs.push(source.base) | |
} | |
} | |
// process | |
if (typeof sources === 'string') { | |
dirs.push(sources) | |
} | |
else if (Array.isArray(sources)) { | |
sources.forEach(source => { | |
if (typeof source === 'string') { | |
dirs.push(source) | |
} | |
else { | |
addSource(source) | |
} | |
}) | |
} | |
else { | |
Object.keys(sources).forEach((key: string) => { | |
addSource(sources[key]) | |
}) | |
} | |
} | |
// process dirs | |
const logs: { route: string, redirect: string }[] = [] | |
for (const dir of dirs) { | |
if (Fs.existsSync(dir)) { | |
const paths = walk(dir) | |
paths.forEach(absPath => { | |
const redirect = absPath.substring(dir.length) | |
const route = redirect.replace(/\/[^/]+$/, '') | |
if (route !== '') { | |
// debug | |
logs.push({ route, redirect }) | |
// redirect on server | |
extendRouteRules(route, { redirect }) | |
// redirect on client | |
extendPages(pages => { | |
pages.push({ | |
file: '', // for Nuxt < v3.3.1 | |
path: route, | |
redirect | |
}) | |
}) | |
} | |
}) | |
} | |
} | |
// log | |
if (debug) { | |
const max: number = Math.max(...logs.map(log => log.route.length)) | |
const output = logs.map(({ route, redirect }) => { | |
return `[${name}] ${route + ' '.repeat(max - route.length)} -> ${redirect}` | |
}) | |
console.log(output.join('\n')) | |
} | |
}, | |
}) | |
function walk (folder: string, paths: string[] = []) { | |
// variables | |
const entries = Fs.readdirSync(folder) | |
let index | |
let first | |
// walk children | |
for (let entry of entries) { | |
const path = Path.join(folder, entry) | |
if (Fs.statSync(path).isDirectory()) { | |
walk(path, paths) | |
} | |
else if (/\.mdx?$/.test(entry)) { | |
if (!first) { | |
first = path | |
} | |
if (/^(\d+\.)?index\.mdx?$/.test(entry)) { | |
index = path | |
} | |
} | |
} | |
if (!index && first) { | |
paths.push(first.replace(/\d+\.|\.mdx?$/g, '')) | |
} | |
return paths | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[content-indexer] redirect: /blog/productivity -> /blog/productivity/less-tabs | |
[content-indexer] redirect: /help/getting-started -> /help/getting-started/intro | |
[content-indexer] redirect: /help/interface -> /help/interface/history | |
[content-indexer] redirect: /help/open-tabs -> /help/open-tabs/display | |
[content-indexer] redirect: /help/closed-tabs -> /help/closed-tabs/history | |
[content-indexer] redirect: /help/tools -> /help/tools/data | |
[content-indexer] redirect: /help/customisation -> /help/customisation/personalisation |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment