Lunr integration for Astro; client-side search for statically hosted pages.
0 | import fs from 'node:fs'; | ||
1 | import path from 'node:path'; | ||
... | |||
54 | } | ||
55 | |||
56 | + | ||
57 | + | export function createVitePlugin({ config }) { | |
58 | + | return { | |
59 | + | name: 'astro-lunr:dev-server', | |
60 | + | configureServer(viteServer) { | |
61 | + | viteServer.middlewares.use((req, res, next) => { | |
62 | + | if(req.url.endsWith("/idx.json") || req.url.endsWith("/docs.json")){ | |
63 | + | let path = req.url.slice(1); | |
64 | + | if(config.base && config.base != "./"){ | |
65 | + | let base = config.base.startsWith("./") ? config.base.slice(2) : config.base; | |
66 | + | path = path.replace(base, "./"); | |
67 | + | } | |
68 | + | let preBuiltPath = new URL(path, config.outDir); | |
69 | + | try { | |
70 | + | var stat = fs.statSync(preBuiltPath); | |
71 | + | } catch(err){ | |
72 | + | err.message = "Could not find pre-built lunr-files - search is not available without first building your astro-pages at least once. " + err.toString(); | |
73 | + | throw err; | |
74 | + | } | |
75 | + | res.writeHead(200, { | |
76 | + | 'Content-Type': 'application/json', | |
77 | + | 'Content-Length': stat.size | |
78 | + | }); | |
79 | + | return fs.createReadStream(preBuiltPath).pipe(res); | |
80 | + | } | |
81 | + | return next(); | |
82 | + | }); | |
83 | + | }, | |
84 | + | }; | |
85 | + | } | |
86 | + | ||
87 | + | function getViteConfiguration(config) { | |
88 | + | return { | |
89 | + | plugins: [createVitePlugin(config)] | |
90 | + | }; | |
91 | + | } | |
92 | + | ||
93 | + | ||
94 | export default function createPlugin({pathFilter, subDir, documentFilter, initialize, mapDocument, verbose}){ | ||
95 | let config = {}; | ||
... | |||
104 | serverEntrypoint: 'astro-lunr/server/renderer.js', | ||
105 | }); | ||
106 | + | options.updateConfig({ vite: getViteConfiguration(options) }); | |
107 | } | ||
108 | }, | ||
... | |||
156 | } | ||
157 | } |
0 | |||
1 | |||
... | |||
100 | ### Searching in Dev-mode | ||
101 | |||
102 | - | Due to the nature of indexing, to properly search in dev-mode, one needs to first build the page at least once to create the index | |
103 | + | Due to the nature of indexing, to properly search in dev-mode, one needs to first build the pages at least once to create the index | |
104 | |||
105 | - | Furthermore, to make the dev-server accept the index-files, you might need to symbolically link the index-files from the public-folder. These should be included in `.gitignore` or equivalent. | |
106 | - | ||
107 | - | Example of how this is done automatically for `astro-git-view`: | |
108 | - | ||
109 | - | ```json | |
110 | - | "scripts": { | |
111 | - | "dev": "(ln -s ../dist/lunr ./public/lunr 2> /dev/null || true) && astro dev", | |
112 | - | "start": "(ln -s ../dist/lunr ./public/lunr 2> /dev/null || true) && astro dev", | |
113 | - | "build": "(rm ./public/lunr 2> /dev/null || true) && astro build", | |
114 | - | "preview": "astro preview" | |
115 | - | }, | |
116 | - | ``` | |
117 | - | ||
118 | - | A potential future solution would be to "trick" the dev-server into serving certain files from `./dist` without the end-user needing to think, or by writing the files to both dist and public. | |
119 | - | ||
120 | ### Searching in SSR-mode | ||
121 | |||
122 | To properly search files that are not usually genereated in the build-step, you would need to have a separate build-step that includes all pages that might be generated. | ||
123 |