Skip to content

Commit

Permalink
Fix empty index when JavaScript is disabled
Browse files Browse the repository at this point in the history
  • Loading branch information
meduzen authored Nov 12, 2023
1 parent 6b537c2 commit 5b83428
Show file tree
Hide file tree
Showing 6 changed files with 107 additions and 110 deletions.
12 changes: 12 additions & 0 deletions vitepress/.vitepress/config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,18 @@ export default defineConfig({
['link', { rel: 'alternate', type: 'application/rss+xml', title: APP_TITLE, href: `${APP_URL}/feed.xml` }]
],

vite: {
ssr: {
/**
* Prevent “module not found” error. Solution from
* https://github.com/vuejs/vitepress/issues/2832#issuecomment-1689498631
* or any search using `noExternal` on Vitepress and Vite repos.
* @todo: Shouldn’t be needed on Vite 5.
*/
noExternal: ['datetime-attribute'],
},
},

themeConfig: {
// https://vitepress.dev/reference/default-theme-config
nav: [
Expand Down
51 changes: 44 additions & 7 deletions vitepress/.vitepress/theme/ArticlesIndex.vue
Original file line number Diff line number Diff line change
@@ -1,13 +1,50 @@
<script setup>
import { defineClientComponent } from 'vitepress'
import { onBeforeMount, reactive } from 'vue'
import { data as importedData } from '../../articles.data'
import { datetime } from 'datetime-attribute'
import Tags from './components/Tags.vue';
/**
* This components only runs in the browser, hence the dynamic import.
* https://vitepress.dev/guide/ssr-compat#defineclientcomponent
*/
const ArticlesIndexClient = defineClientComponent(() => import('./ArticlesIndexClient.vue'))
// The following declaration is just to import type autocompletion. 😑
/** @type {Record<string, import('vitepress').ContentData[]>} */
const data = reactive(importedData)
// Normalize date
data.forEach(article => {
article.frontmatter.publishedAt = new Date(article.frontmatter.publishedAt)
})
onBeforeMount(() => {
/**
* Make sure the excerpt links to the post URL.
*
* Ideally this transformation should be done at build time, but I don’t
* want to add a DOM Parser library because Node doesn’t have one. 😑
* It turns an excerpt into a proper link for the content index.
*/
import('./utils/frontmatter').then(({ excerptToLink }) => {
data.forEach(excerptToLink)
})
})
const dateFormatter = new Intl.DateTimeFormat('en-GB', {
day: 'numeric',
month: 'long',
year: 'numeric',
})
</script>

<template>
<ArticlesIndexClient />
<template v-for="({ excerpt, frontmatter: { title, publishedAt, tags }, url }) in data">

<h2><a :href="url" v-html="title"/></h2>

<time :datetime="datetime(new Date(publishedAt), 'year')">
{{ dateFormatter.format(publishedAt) }}
</time>

<tags v-if="tags" :tags="tags" />

<p v-if="excerpt" v-html="excerpt"></p>
</template>
</template>
43 changes: 0 additions & 43 deletions vitepress/.vitepress/theme/ArticlesIndexClient.vue

This file was deleted.

58 changes: 51 additions & 7 deletions vitepress/.vitepress/theme/NotesIndex.vue
Original file line number Diff line number Diff line change
@@ -1,13 +1,57 @@
<script setup>
import { defineClientComponent } from 'vitepress'
import { onBeforeMount, reactive } from 'vue'
import { data as importedData } from '../../notes.data'
import { datetime } from 'datetime-attribute'
/**
* This components only runs in the browser, hence the dynamic import.
* https://vitepress.dev/guide/ssr-compat#defineclientcomponent
*/
const NotesIndexClient = defineClientComponent(() => import('./NotesIndexClient.vue'))
// The following declaration is just to import type autocompletion. 😑
/** @type {Record<string, import('vitepress').ContentData[]>} */
const data = reactive(importedData)
// Sort years
const years = Object.keys(data).sort((a, b) => b - a)
// Normalize date
years.forEach(year => data[year].forEach(note => {
note.frontmatter.publishedAt = new Date(note.frontmatter.publishedAt)
}))
onBeforeMount(() => {
/**
* Make sure the excerpt links to the post URL.
*
* Ideally this transformation should be done at build time, but I don’t
* want to add a DOM Parser library because Node doesn’t have one. 😑
* It turns an excerpt into a proper link for the content index.
*/
import('./utils/frontmatter').then(({ excerptToLink }) => {
years.forEach(year => data[year].forEach(excerptToLink))
})
})
const dateFormatter = new Intl.DateTimeFormat('en-GB', {
day: 'numeric',
month: 'long',
})
</script>

<template>
<NotesIndexClient />
<template v-for="year in years">

<h2><time :datetime="datetime(new Date(year), 'year')">{{ year }}</time></h2>

<ul>
<li v-for="({ excerptTransformed, frontmatter: { title, publishedAt, excerpt }, url }) in data[year]">
<p>
<time :datetime="datetime(publishedAt)">
{{ dateFormatter.format(publishedAt) }}
</time>:

<span v-if="excerptTransformed" v-html="excerpt"/>
<a v-else :href="url">{{ title }}</a>
</p>
</li>
</ul>

</template>
</template>
49 changes: 0 additions & 49 deletions vitepress/.vitepress/theme/NotesIndexClient.vue

This file was deleted.

4 changes: 0 additions & 4 deletions vitepress/.vitepress/theme/index.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
import './custom.css'
import DefaultTheme from 'vitepress/theme'
// import NotesIndex from './NotesIndex.vue'

export default {
extends: DefaultTheme,
// enhanceApp({ app }) {
// app.component('notes-index', NotesIndex)
// }
}

0 comments on commit 5b83428

Please sign in to comment.