Server read data from public

Hello, In server/api I have data script, that reads file from public, and returns json
import fs from 'fs';
import {parse} from 'smol-toml';
import path from 'path';
import url from 'url';

export default defineEventHandler((event) => {
try {
const dataRaw = fs.readFileSync(path.relative(process.cwd(), './public/personal/main.toml'));
const data = parse(dataRaw.toString());
return data;
} catch (e) {
console.log(e);
return {}
}
})
import fs from 'fs';
import {parse} from 'smol-toml';
import path from 'path';
import url from 'url';

export default defineEventHandler((event) => {
try {
const dataRaw = fs.readFileSync(path.relative(process.cwd(), './public/personal/main.toml'));
const data = parse(dataRaw.toString());
return data;
} catch (e) {
console.log(e);
return {}
}
})
When I build and run it locally, everything is fine; but when I try to deploy it with netlify I get empty response from api/data. Most likely it is due to current working directory (process.cwd()) being outside of dist folder, however I have no idea, how else I can load that data, as relative path to public differs between dev and build.
3 Replies
kapa.ai
kapa.ai3w ago
Hi @𝔪𝔟𝔩𝔢. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave: ---------------------- To address your issue with reading files from the public directory in a Nuxt 3 server API route, especially when deploying to Netlify, we need to make some adjustments to your code. The problem likely stems from the way file paths are resolved in different environments. Here's a solution that should work both in development and production: 1. First, move your data file from public/personal/main.toml to the server/ directory. This is because the public directory is meant for static assets served directly by the web server, not for server-side file operations. 2. Update your server API route to use the correct path resolution method. Here's the modified code:
import fs from 'fs'
import { parse } from 'smol-toml'
import { fileURLToPath } from 'url'
import { dirname, join } from 'path'

export default defineEventHandler((event) => {
try {
const currentDir = dirname(fileURLToPath(import.meta.url))
const filePath = join(currentDir, '../main.toml')
const dataRaw = fs.readFileSync(filePath, 'utf-8')
const data = parse(dataRaw)
return data
} catch (e) {
console.error(e)
return {}
}
})
import fs from 'fs'
import { parse } from 'smol-toml'
import { fileURLToPath } from 'url'
import { dirname, join } from 'path'

export default defineEventHandler((event) => {
try {
const currentDir = dirname(fileURLToPath(import.meta.url))
const filePath = join(currentDir, '../main.toml')
const dataRaw = fs.readFileSync(filePath, 'utf-8')
const data = parse(dataRaw)
return data
} catch (e) {
console.error(e)
return {}
}
})
This approach uses import.meta.url to get the current module's URL and then resolves the path to the main.toml file relative to the current file's location. This should work consistently across different environments, including Netlify. The reason for moving the file out of the public directory is explained in the Nuxt 3 documentation on assets:
Nuxt won't serve files in the assets/ directory at a static URL like /assets/my-file.png. If you need a static URL, use the public/ directory.
By moving the file to the server/ directory, we ensure that it's not publicly accessible but can be read by your server-side code. If you absolutely need to keep the file in the public directory for some reason, you could try using the useRuntimeConfig composable to access the public directory path, as mentioned in the Nuxt 3 documentation on runtime config. However, this approach is less straightforward and may require additional configuration. Remember to update your build settings on Netlify to ensure that Nuxt is building correctly for server-side rendering (SSR) mode. Nuxt 3 Assets Documentation Nuxt 3 Runtime Config Documentation ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai3w ago
<@216277353951789065> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
𝔪𝔟𝔩𝔢
𝔪𝔟𝔩𝔢OP3w ago
I am currently trying to use this plugin - https://github.com/originjs/origin.js/tree/main/packages/vite-plugin-content; but it is not f-ing working
[9:01:24 PM] WARN [plugin inject] personal/main.toml: rollup-plugin-inject: failed to parse /home/mble/Code/repos/mbledkowski/website/personal/main.toml. Consider restricting the plugin to particular files via options.include


ERROR RollupError: personal/main.toml (60:23): Identifier cannot follow number (Note that you need plugins to import files that are not JavaScript)
[9:01:24 PM] WARN [plugin inject] personal/main.toml: rollup-plugin-inject: failed to parse /home/mble/Code/repos/mbledkowski/website/personal/main.toml. Consider restricting the plugin to particular files via options.include


ERROR RollupError: personal/main.toml (60:23): Identifier cannot follow number (Note that you need plugins to import files that are not JavaScript)
import content from '@originjs/vite-plugin-content'

// https://nuxt.com/docs/api/configuration/nuxt-config
export default defineNuxtConfig({
devtools: { enabled: true },
modules: ["@nuxtjs/tailwindcss", "@nuxt/image", "@nuxt/icon"],
image: {
quality: 96,
format: ['avif','webp']
},
vite: {
plugins: [content()]
}
})
import content from '@originjs/vite-plugin-content'

// https://nuxt.com/docs/api/configuration/nuxt-config
export default defineNuxtConfig({
devtools: { enabled: true },
modules: ["@nuxtjs/tailwindcss", "@nuxt/image", "@nuxt/icon"],
image: {
quality: 96,
format: ['avif','webp']
},
vite: {
plugins: [content()]
}
})
I need help 😥 I solved that problem
import content from '@originjs/vite-plugin-content'

// https://nuxt.com/docs/api/configuration/nuxt-config
export default defineNuxtConfig({
devtools: { enabled: true },
modules: ["@nuxtjs/tailwindcss", "@nuxt/image", "@nuxt/icon"],
image: {
quality: 96,
format: ['avif','webp']
},
nitro: {
rollupConfig: {
// @ts-ignore
plugins: [content()]
}
}
})
import content from '@originjs/vite-plugin-content'

// https://nuxt.com/docs/api/configuration/nuxt-config
export default defineNuxtConfig({
devtools: { enabled: true },
modules: ["@nuxtjs/tailwindcss", "@nuxt/image", "@nuxt/icon"],
image: {
quality: 96,
format: ['avif','webp']
},
nitro: {
rollupConfig: {
// @ts-ignore
plugins: [content()]
}
}
})
import data from '~/assets/personal/main.toml';

export default defineEventHandler(async (event) => {
try {
return data;
} catch (e) {
console.log(e);
return {}
}
})
import data from '~/assets/personal/main.toml';

export default defineEventHandler(async (event) => {
try {
return data;
} catch (e) {
console.log(e);
return {}
}
})

Did you find this page helpful?