Home > Back-end >  Nuxt 3: Programmatically Access /public Files
Nuxt 3: Programmatically Access /public Files

Time:12-03

I have a project using Nuxt 3, with a lot of images in the /public directory (and subdirectories). Now I would like to implement a simple gallery showing all images in the directory (or specified subdirectory). Is there a way to programmatically access all files in the directory, so that I can just do something like this:

<script setup>
let images = ???
</script>

<template>
  <img v-for="image in images" :key="image.path" :scr="image.path" alt="" />
</template>

CodePudding user response:

Yes, you can programmatically access the files in the /public directory in your Nuxt.js project by using the require.context() method. This method allows you to specify a directory to search, and it returns an object with information about all the files in that directory.

Here is an example of how you can use this method to access the files in your /public directory:

<script>
import { requireContext } from '@nuxt/utils'

// Use require.context() to search the /public directory for files
const imagesContext = requireContext('@/public', true, /\.(png|jpeg|jpg|gif)$/)

// Get the path and name of each image file
const imagePaths = imagesContext.keys()
const imageNames = imagePaths.map(path => imagesContext(path).default)

export default {
  data() {
    return {
      images: imageNames
    }
  }
}
</script>

<template>
  <img v-for="image in images" :key="image.path" :src="image.path" alt="" />
</template>

In this example, we use the require.context() method to search the /public directory for image files (with the extensions .png, .jpeg, .jpg, and .gif). We then use the keys() method to get the path and name of each file, and we store these values in the images array.

Finally, in the template, we loop through the images array and render an element for each image, using the path property of each image as the src attribute.

CodePudding user response:

You could do the following using a composable

composables/useAssets.js

import fs from 'fs';
import path from 'path';

const folderPath = './public';
const relativeFolderPath = path.relative(process.cwd(), folderPath);

export default function () {
  const files = fs
    .readdirSync(folderPath)
    .filter((file) => file.match(/.*\.(jpg|png?)/gi));

  const filesPaths = files.map(
    (fileName) => `/_nuxt/${relativeFolderPath}/${fileName}`
  );

  return filesPaths;
}

YourComponent.vue

<script setup>
  const assets = useAssets();
</script>

<template>
  <div>
    <img :src="item" v-for="item in assets" :key="item" />
 </div>
</template>

Your basically reading all the files in the specified folder which you select by configuring folderPath then get the relative path of that folder from the root to append it to file paths later (process.cwd() gets the root project path).

after getting the matched assets and storing the array in files, we're using map to construct a new array with correct relative paths of the files in order for nuxt to read it correctly

  • Related