I have an error when I go to a markdown document from my main page, and I click on the arrow to go back in my browser.
It notes me this error:
500
Failed to fetch dynamically imported module: http://localhost:3000/_nuxt/pages/index.vue
Here is the full error:
nuxt] error caught during app initialization H3Error:
Failed to fetch dynamically imported module: http://localhost:3000/_nuxt/pages/index.vue
Caused by: TypeError: Failed to fetch dynamically imported module: http://localhost:3000/_nuxt/pages/index.vue
Here is my […slug].vue code:
<template>
<main>
<div>
<content-renderer :value="prodData" />
</div>
</main>
</template>
<script lang="ts" setup>
import { queryContent, useAsyncData, useRoute } from '#imports';
const route = useRoute();
const path = route.path;
const { data } = await useAsyncData('content-data', () =>
queryContent(path).findOne(),
);
const prodData = data.value;
</script>
Here is my index.vue code:
<template>
<AllPage>
<Projects />
</AllPage>
</template>
<script lang="ts" setup></script>
<style scoped></style>
this is the Projects component:
<template>
<div class="d-flex flex-column h-100 ga-10">
<Card
v-for="doc in docs"
:key="doc._path"
:description="doc.description"
:image="doc.firstImage"
:path="doc._path"
:title="doc.title"
/>
</div>
</template>
<script lang="ts" setup>
import { queryContent, useAsyncData } from '#imports';
function extractFirstImage(content) {
if (!content || !content.children) return null; // Checks that the content exists and has children
// Recursively searches through children to find the first image
for (const node of content.children) {
if (
node.type === 'element' &&
node.tag === 'img' &&
node.props &&
node.props.src
) {
return node.props.src; // Returns the URL of the first image found
}
// If the child has children, call the function recursively
if (node.children) {
const image = extractFirstImage(node);
if (image) return image;
}
}
return null; // No image found
}
const { data } = await useAsyncData('projects', () =>
queryContent('/projects').find(),
);
const docs = data.value.map((doc) => ({
...doc,
firstImage: extractFirstImage(doc.body), // Extracts the first image
}));
</script>
<style scoped>
@import 'assets/css/dark-theme-content.css';
</style>
This is the Card component :
<template>
<v-card :href="path" class="project-card mx-auto rounded-lg" width="300px">
<div class="img-container pa-3 w-100">
<img
v-if="displayImage"
:src="images[`${displayImage}`]"
alt="Image du document"
class="card-img w-100 h-100 rounded-lg"
/>
</div>
<v-card-title class="card-title">{{ title }}</v-card-title>
<v-card-subtitle class="card-description pb-3"
>{{ description }}
</v-card-subtitle>
</v-card>
</template>
<script lang="ts" setup>
import { filename } from 'pathe/utils';
const props = defineProps({
title: String,
description: String,
image: String,
path: String,
});
console.log(props.path);
const displayImage = props.image
?.replace('../../assets/img/content/', '')
.replace(/.(png|jpe?g|gif|bmp|webp)$/gi, '');
// Import all image files from the @/assets/img/content folder
const glob = import.meta.glob(`@/assets/img/content/*`, {
eager: true, // Immediately loads images to make them available as soon as the component is rendered
});
// Creates an images object where each key is a filename, and each value is the image URL
const images = Object.fromEntries(
Object.entries(glob).map(([key, value]) => [filename(key), value.default]),
);
</script>
<style scoped></style>
This is my nuxt configuration file:
import vuetify, { transformAssetUrls } from 'vite-plugin-vuetify';
export default defineNuxtConfig({
css: ['~/assets/css/style.css'],
compatibilityDate: '2024-04-03',
devtools: { enabled: true },
app: {
head: {
meta: [
{ name: 'viewport', content: 'width=device-width, initial-scale=1' }
],
link: [
{
rel: 'stylesheet',
href: 'https://cdnjs.cloudflare.com/ajax/libs/modern-normalize/3.0.1/modern-normalize.min.css'
},
{
rel: 'preconnect', href: 'https://fonts.googleapis.com'
},
{ rel: 'preconnect', href: 'https://fonts.gstatic.com' },
{
href: 'https://fonts.googleapis.com/css2?family=Ubuntu:ital,wght@0,300;0,400;0,500;0,700;1,300;1,400;1,500;1,700&display=swap',
rel: 'stylesheet'
}
],
script: [
{
src: 'https://cdn.anychart.com/releases/v8/js/anychart-base.min.js'
},
{
src: 'https://cdn.anychart.com/releases/v8/js/anychart-tag-cloud.min.js'
}
]
}
},
build: {
transpile: ['vuetify']
},
modules: [
(_options, nuxt) => {
nuxt.hooks.hook('vite:extendConfig', (config) => {
// @ts-expect-error
config.plugins.push(vuetify({ autoImport: true }));
});
},
'@nuxt/content'
],/*
content: {
documentDriven: true
}, */
vite: {
vue: {
template: {
transformAssetUrls
}
}
},
runtimeConfig: {
public: {
imageBasePath: '~/assets/img'
}
}
});