2023-01-15 03:36:13 +00:00
---
2023-08-17 20:30:13 +00:00
title: Spreadsheets in VueJS Sites with NuxtJS
sidebar_label: NuxtJS
description: Make static websites from spreadsheets using NuxtJS. Seamlessly integrate data into the data layer using SheetJS. Create content without leaving the comfort of Excel.
2023-02-28 11:40:44 +00:00
pagination_prev: demos/net/index
pagination_next: demos/mobile/index
2023-01-15 03:36:13 +00:00
---
2023-04-27 09:12:19 +00:00
import current from '/version.js';
2023-05-01 01:27:02 +00:00
import CodeBlock from '@theme/CodeBlock';
2023-04-27 09:12:19 +00:00
2023-08-17 20:30:13 +00:00
[Nuxt Content ](https://content.nuxtjs.org/ ) is a file-based CMS for NuxtJS,
enabling static-site generation and on-demand server rendering from data files.
2023-01-15 03:36:13 +00:00
2023-08-17 20:30:13 +00:00
[SheetJS ](https://sheetjs.com ) is a JavaScript library for reading and writing
data from spreadsheets.
This demo uses NuxtJS and SheetJS to pull data from a spreadsheet and display
the content in an HTML table.
:::info pass
There were breaking changes between VueJS 2.x and VueJS 3.x. Since many projects
still use VueJS 2.x, this demo includes examples for both versions of VueJS.
:::
The ["Nuxt Content v1" ](#nuxt-content-v1 ) section explores "parsers" for NuxtJS
Content v1 (paired with VueJS 2.x and NuxtJS 2.x)
The ["Nuxt Content v2" ](#nuxt-content-v2 ) section explores "transformers" for
NuxtJS Content v2 (paired with VueJS 3.x and NuxtJS 3.x)
2023-06-02 02:17:56 +00:00
2023-01-20 02:25:16 +00:00
:::note
2023-05-01 01:27:02 +00:00
The following deployments were tested:
| Nuxt Content | Nuxt | Date |
|:-------------|:---------|:-----------|
2023-08-17 20:30:13 +00:00
| `1.15.1` | `2.17.1` | 2023-08-16 |
| `2.7.2` | `3.6.5` | 2023-08-16 |
2023-06-02 02:17:56 +00:00
:::
:::caution Telemetry
Nuxt embeds telemetry. According to the developers, it is disabled by default.
To explicitly disable telemetry, the official documentation recommends:
```bash
npx nuxt telemetry disable
```
At the time the demo was last tested, this command did not work. Instead, a
option should be added in `nuxt.config.ts` or `nuxt.config.js` for Nuxt 3 sites:
2023-06-03 09:10:50 +00:00
```js title="nuxt.config.js"
2023-06-02 02:17:56 +00:00
// ...
// highlight-start
export default defineNuxtConfig({
// @ts -ignore
telemetry: false,
// highlight-end
// ...
})
```
A global setting can be added to `.nuxtrc` in the user home directory:
```ini title=".nuxtrc"
telemetry.enabled=false
```
2023-01-20 02:25:16 +00:00
:::
2023-05-01 01:27:02 +00:00
## Nuxt Content v1
2023-08-17 20:30:13 +00:00
Nuxt Content v1 is designed to work with NuxtJS v2 and VueJS v2.
2023-05-01 01:27:02 +00:00
2023-05-25 01:36:15 +00:00
The following diagram depicts the workbook waltz:
```mermaid
flowchart LR
file[(workbook\nfile)]
subgraph SheetJS operations
buffer(NodeJS\nBuffer)
aoo(array of\nobjects)
end
html{{HTML\nTABLE}}
file --> |nuxt.config.js\ncustom parser| buffer
buffer --> |nuxt.config.js\ncustom parser| aoo
aoo --> |index.vue\ntemplate| html
```
2023-08-17 20:30:13 +00:00
### Installation
2023-01-15 03:36:13 +00:00
2023-08-17 20:30:13 +00:00
The [SheetJS NodeJS Module ](/docs/getting-started/installation/nodejs ) can be
imported from `nuxt.config.js` for build-time processing.
2023-01-15 03:36:13 +00:00
2023-08-17 20:30:13 +00:00
### Custom Parser
:::info pass
Custom parsers receive the file content interpreted as UTF-8 strings. For binary
formats including XLSX and XLS, the data is corrupt and cannot be used.
The workaround involves safely re-reading the spreadsheets.
:::
The second argument passed to the parser is an object. The `path` property of
the object is the path to the file.
The SheetJS `readFile` [^1] method can locate and parse the spreadsheet files.
The `sheet_to_json` [^2] utility function can generate arrays of row objects for
use in NuxtJS pages:
```js title="Custom Parser (in nuxt.config.js)"
2023-01-15 03:36:13 +00:00
import { readFile, utils } from 'xlsx';
2023-08-17 20:30:13 +00:00
/* This will be called when the files change */
2023-01-15 03:36:13 +00:00
const parseSheet = (file, { path }) => {
2023-08-17 20:30:13 +00:00
/* `path` is a path that can be read with `XLSX.readFile` */
2023-01-15 03:36:13 +00:00
const wb = readFile(path);
2023-08-17 20:30:13 +00:00
/* iterate through each worksheet name and generate row objects */
const o = wb.SheetNames.map(name => ({
name: name,
data: utils.sheet_to_json(wb.Sheets[name])
}));
/* The final result must be stored in the `data` key of an object */
2023-01-15 03:36:13 +00:00
return { data: o };
2023-06-02 02:17:56 +00:00
};
2023-08-17 20:30:13 +00:00
```
2023-01-15 03:36:13 +00:00
2023-08-17 20:30:13 +00:00
### Configuration
Using `content.extendParser` [^3], Nuxt Content will use custom parsers.
The property is expected to be an object whose keys are file extensions (with
the `.` before the extension) and whose values are custom parser functions.
The relevant part of the config is shown below. In this snippet, the custom
parser `parseSheet` will be associated with XLSX, XLS and NUMBERS files:
```js title="nuxt.config.js"
2023-01-15 03:36:13 +00:00
export default {
// ...
// content.extendParser allows us to hook into the parsing step
content: {
extendParser: {
// the keys are the extensions that will be matched. The "." is required
".numbers": parseSheet,
".xlsx": parseSheet,
".xls": parseSheet,
// can add other extensions like ".fods" as desired
}
},
// ...
}
```
2023-01-20 02:25:16 +00:00
### Template Use
2023-01-15 03:36:13 +00:00
When a spreadsheet is placed in the `content` folder, Nuxt will find it. The
data can be referenced in a view with `asyncData` . The name should not include
the extension, so `"sheetjs.numbers"` would be referenced as `"sheetjs"` :
2023-08-17 20:30:13 +00:00
```js title="Script section of .vue VueJS page"
2023-01-15 03:36:13 +00:00
async asyncData ({$content}) {
return {
// $content('sheetjs') will match files with extensions in nuxt.config.js
data: await $content('sheetjs').fetch()
};
}
```
In the template, `data.data` is an array of objects. Each object has a `name`
property for the worksheet name and a `data` array of row objects. This maps
2023-08-17 20:30:13 +00:00
neatly with nested `v-for` [^4]:
2023-01-15 03:36:13 +00:00
2023-08-17 20:30:13 +00:00
```xml title="Template section of .vue VueJS page"
2023-01-15 03:36:13 +00:00
<!-- loop over the worksheets -->
< div v-for = "item in data.data" v-bind:key = "item.name" >
< table >
<!-- loop over the rows of each worksheet -->
< tr v-for = "row in item.data" v-bind:key = "row.Index" >
<!-- here `row` is a row object generated from sheet_to_json -->
< td > {{ row.Name }}< / td >
< td > {{ row.Index }}< / td >
< / tr >
< / table >
< / div >
```
2023-01-20 02:25:16 +00:00
### Nuxt Content Demo
2023-01-15 03:36:13 +00:00
2023-08-17 20:30:13 +00:00
:::caution pass
2023-06-02 02:17:56 +00:00
2023-08-17 20:30:13 +00:00
For some older versions, parts of the Nuxt dependency tree did not support
NodeJS version 20. `EBADENGINE` warnings were displayed during app creation:
2023-06-02 02:17:56 +00:00
```
npm WARN EBADENGINE Unsupported engine {
npm WARN EBADENGINE package: '@nuxt/types@2.16.3',
npm WARN EBADENGINE required: { node: '^14.18.0 || ^16.10.0 || ^17.0.0 || ...
npm WARN EBADENGINE current: { node: 'v20.2.0', npm: '9.6.6' }
npm WARN EBADENGINE }
```
The recommended solution is to switch to Node 18.
:::
2023-01-15 03:36:13 +00:00
1) Create a stock app:
```bash
2023-06-02 02:17:56 +00:00
npx create-nuxt-app@4.0.0 sheetjs-nuxt
2023-01-15 03:36:13 +00:00
```
When prompted, enter the following options:
2023-06-02 02:17:56 +00:00
- `Project name` : press Enter (use default `sheetjs-nuxt` )
2023-01-15 03:36:13 +00:00
- `Programming language` : press Down Arrow (`TypeScript` selected) then Enter
- `Package manager` : select `Npm` and press Enter
- `UI framework` : select `None` and press Enter
- `Nuxt.js modules` : scroll to `Content` , select with Space, then press Enter
- `Linting tools` : press Enter (do not select any Linting tools)
- `Testing framework` : select `None` and press Enter
- `Rendering mode` : select `Universal (SSR / SSG)` and press Enter
- `Deployment target` : select `Static (Static/Jamstack hosting)` and press Enter
- `Development tools` : press Enter (do not select any Development tools)
- `What is your GitHub username?` : press Enter
- `Version control system` : select `None`
The project will be configured and modules will be installed.
2) Install the SheetJS library and start the server:
2023-05-01 01:27:02 +00:00
< CodeBlock language = "bash" > {`\
2023-06-02 02:17:56 +00:00
cd sheetjs-nuxt
2023-05-01 01:27:02 +00:00
npm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz
npm run dev`}
< / CodeBlock >
2023-01-15 03:36:13 +00:00
When the build finishes, the terminal will display a URL like:
```
ℹ Listening on: http://localhost:64688/
```
The server is listening on that URL. Open the link in a web browser.
3) Download < https: // sheetjs . com / pres . xlsx > and move to the `content` folder.
```bash
curl -L -o content/pres.xlsx https://sheetjs.com/pres.xlsx
```
4) Modify `nuxt.config.js` as follows:
- Add the following to the top of the script:
```js
import { readFile, utils } from 'xlsx';
// This will be called when the files change
const parseSheet = (file, { path }) => {
// `path` is a path that can be read with `XLSX.readFile`
const wb = readFile(path);
const o = wb.SheetNames.map(name => ({ name, data: utils.sheet_to_json(wb.Sheets[name])}));
return { data: o };
2023-06-02 02:17:56 +00:00
};
2023-01-15 03:36:13 +00:00
```
- Look for the exported object. There should be a `content` property:
```js
// Content module configuration: https://go.nuxtjs.dev/config-content
content: {},
```
Replace the property with the following definition:
```js
// content.extendParser allows us to hook into the parsing step
content: {
extendParser: {
// the keys are the extensions that will be matched. The "." is required
".numbers": parseSheet,
".xlsx": parseSheet,
".xls": parseSheet,
// can add other extensions like ".fods" as desired
}
},
```
(If the property is missing, add it to the end of the exported object)
5) Replace `pages/index.vue` with the following:
2023-08-17 20:30:13 +00:00
```html title="pages/index.vue"
2023-01-15 03:36:13 +00:00
<!-- sheetjs (C) 2013 - present SheetJS - - https://sheetjs.com -->
< template > < div >
< div v-for = "item in data.data" v-bind:key = "item.name" >
< h2 > {{ item.name }}< / h2 >
< table > < thead > < tr > < th > Name< / th > < th > Index< / th > < / tr > < / thead > < tbody >
< tr v-for = "row in item.data" v-bind:key = "row.Index" >
< td > {{ row.Name }}< / td >
< td > {{ row.Index }}< / td >
< / tr >
< / tbody > < / table >
< / div >
< / div > < / template >
< script >
export default {
async asyncData ({$content}) {
return {
data: await $content('pres').fetch()
};
}
};
< / script >
```
The browser should refresh to show the contents of the spreadsheet. If it does
not, click Refresh manually or open a new browser window.
![Nuxt Demo end of step 5 ](pathname:///nuxt/nuxt5.png )
2023-06-03 09:10:50 +00:00
6) To verify that live reload works, open `pres.xlsx` from the `content` folder
2023-01-15 03:36:13 +00:00
in Excel. Add a new row to the bottom and save the file:
![Adding a new line to `pres.xlsx` ](pathname:///nuxt/nuxl6.png )
The server terminal window should show a line like:
```
ℹ Updated ./content/pres.xlsx @nuxt/content 05:43:37
```
The page should automatically refresh with the new content:
![Nuxt Demo end of step 6 ](pathname:///nuxt/nuxt6.png )
7) Stop the server (press `CTRL+C` in the terminal window) and run
```bash
npm run generate
```
This will create a static site in the `dist` folder, which can be served with:
```bash
npx http-server dist
```
2023-05-03 03:40:40 +00:00
Accessing the page `http://localhost:8080` will show the page contents. Verifying
2023-01-15 03:36:13 +00:00
the static nature is trivial: make another change in Excel and save. The page
will not change.
2023-01-20 02:25:16 +00:00
## Nuxt Content v2
2023-08-17 20:30:13 +00:00
Nuxt Content v2 is designed to work with NuxtJS v3 and VueJS v3.
2023-01-20 02:25:16 +00:00
2023-05-25 01:36:15 +00:00
The following diagram depicts the workbook waltz:
```mermaid
flowchart LR
file[(workbook\nfile)]
subgraph SheetJS operations
buffer(NodeJS\nBuffer)
aoo(array of\nobjects)
end
html{{HTML\nTABLE}}
file --> |custom module\ntransformer| buffer
buffer --> |custom module\ntransformer| aoo
aoo --> |index.vue\nContentRenderer| html
```
2023-08-17 20:30:13 +00:00
### Installation
The [SheetJS NodeJS Module ](/docs/getting-started/installation/nodejs ) can be
safely imported from `nuxt.config.js` or transformer or module scripts. As long
as the SheetJS modules are not imported in the various `.vue` pages, the library
will not be added to the final page bundle!
### Custom Transformer
2023-01-20 02:25:16 +00:00
Nuxt Content `v2` supports custom transformers for controlling data. Although
the library hard-codes UTF-8 interpretations, the `_id` field currently uses
the pattern `content:` followed by the filename (if files are placed in the
2023-08-17 20:30:13 +00:00
`content` folder directly). This enables a transformer to re-read the file.
< details > < summary > < b > Transformer Details< / b > (click to show)< / summary >
For example, if the file `pres.xlsx` is stored in the `content` folder, NuxtJS
Content will use ID `"content:pres.xlsx"` . `"./content/" + _id.slice(8)` will
be the original path `"./content/pres.xlsx"` .
The NodeJS `resolve` [^5] method will return a file path. `readFileSync` [^6] will
read the file and return a NodeJS `Buffer` . That `Buffer` object can be parsed
with the SheetJS `read` [^7] method. The `sheet_to_json` [^8] utility function can
generate arrays of row objects for use in NuxtJS pages.
2023-01-20 02:25:16 +00:00
2023-08-17 20:30:13 +00:00
< / details >
```ts title="sheetformer.ts (Transformer)"
2023-06-02 02:17:56 +00:00
// @ts -ignore
2023-01-20 02:25:16 +00:00
import { defineTransformer } from "@nuxt/content/transformers/utils";
import { read, utils } from "xlsx";
import { readFileSync } from "node:fs";
import { resolve } from 'node:path';
export default defineTransformer({
name: 'sheetformer',
2023-08-17 20:30:13 +00:00
/* list of file extensions */
2023-01-20 02:25:16 +00:00
extensions: ['.xlsx'],
parse (_id: string, rawContent: string) {
2023-06-02 02:17:56 +00:00
// highlight-start
/* read the underlying file */
const buf = readFileSync(resolve("./content/" + _id.slice(8)));
/* parse */
const wb = read(buf);
// highlight-end
/* generate JS objects for each worksheet */
2023-08-17 20:30:13 +00:00
const body = wb.SheetNames.map(name => ({
name: name,
data: utils.sheet_to_json(wb.Sheets[name])
}));
/* The final result must have the `_id` key and must store data in `body` */
2023-01-20 02:25:16 +00:00
return { _id, body };
}
});
```
2023-08-17 20:30:13 +00:00
The data object returned by the transformer must have the original `_id` key.
The data is stored in the `body` property of the final object.
### Custom Modules
NuxtJS modules are the main mechanism for adding transformers to the pipeline.
< details > < summary > < b > Module Details< / b > (click to show)< / summary >
Due to the structure of the NuxtJS system, modules must be defined in separate
script files. The module script is expected to export a module configured with
`defineNuxtModule` . The setup method is expected to do the following:
- Register itself with the "Nitro" subsystem
- Add the transformer to Nuxt Content in the `content:context` hook
```js title="sheetmodule.ts (Module)"
import { resolve } from 'path'
import { defineNuxtModule } from '@nuxt/kit'
export default defineNuxtModule({
/* module setup method */
setup (_options, nuxt) {
/* register with the nitro subsystem */
nuxt.options.nitro.externals = nuxt.options.nitro.externals || {};
nuxt.options.nitro.externals.inline = nuxt.options.nitro.externals.inline || [];
nuxt.options.nitro.externals.inline.push(resolve('./sheetmodule'));
/* add transformer in the content:context hook */
// @ts -ignore
nuxt.hook('content:context', (contentContext) => {
contentContext.transformers.push(resolve('./sheetformer.ts'));
});
}
});
```
The module must be loaded in `nuxt.config.ts` and added to the `modules` array:
```ts title="nuxt.config.ts"
// highlight-next-line
import SheetJSModule from './sheetmodule'
export default defineNuxtConfig({
// @ts -ignore
telemetry: false,
modules: [
// highlight-next-line
SheetJSModule,
/* it is recommended to load the custom modules before @nuxt/content */
'@nuxt/content'
],
content: {}
});
```
< / details >
### Rendering Data
2023-01-20 02:25:16 +00:00
2023-08-17 20:30:13 +00:00
Pages can pull data using `useAsyncData` in the page setup:
```html title="Script section of .vue VueJS page"
2023-01-20 02:25:16 +00:00
< script setup >
const key = "pres"; // matches pres.xlsx
2023-08-17 20:30:13 +00:00
const { data } = await useAsyncData('x', ()=>queryContent(`/${key}`).findOne());
2023-01-20 02:25:16 +00:00
< / script >
```
2023-08-17 20:30:13 +00:00
Pages should use `ContentRenderer` to reference the data. The `data` variable
from the script setup will be shaped like the return value from the transformer.
`data.body` is an array of objects that holds the worksheet name and data.
```html title="Template section of .vue VueJS page"
< template >
< ContentRenderer :value = "data" >
<!-- data.body is the array defined in the transformer -->
< div v-for = "item in data.body" v-bind:key = "item.name" >
<!-- each item has a "name" string for worksheet name -->
< h2 > {{ item.name }}< / h2 >
<!-- each item has a "body" array of data rows -->
< table > < thead > < tr > < th > Name< / th > < th > Index< / th > < / tr > < / thead > < tbody >
< tr v-for = "row in item.data" v-bind:key = "row.Index" >
<!-- Assuming the sheet uses the columns "Name" and "Index" -->
< td > {{ row.Name }}< / td >
< td > {{ row.Index }}< / td >
< / tr >
< / tbody > < / table >
< / div >
< / ContentRenderer >
< / template >
2023-01-20 02:25:16 +00:00
```
### Nuxt Content 2 Demo
2023-08-17 20:30:13 +00:00
:::caution pass
2023-06-02 02:17:56 +00:00
2023-08-17 20:30:13 +00:00
For some older versions, parts of the Nuxt dependency tree did not support
2023-06-02 02:17:56 +00:00
NodeJS version 20. If the `yarn install` step fails with a message like
```
error @nuxt/kit@3 .4.1: The engine "node" is incompatible with this module.
```
The recommended solution is to switch to Node 18.
:::
2023-01-20 02:25:16 +00:00
1) Create a stock app and install dependencies:
```bash
2023-06-02 02:17:56 +00:00
npx -y nuxi init -t content sheetjs-nc2
2023-01-20 02:25:16 +00:00
cd sheetjs-nc2
2023-06-02 02:17:56 +00:00
npx -y yarn install
npx -y yarn add --dev @types/node
2023-01-20 02:25:16 +00:00
```
2) Install the SheetJS library and start the server:
2023-05-01 01:27:02 +00:00
< CodeBlock language = "bash" > {`\
2023-06-02 02:17:56 +00:00
npx -y yarn add https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz
npx -y yarn dev`}
2023-05-01 01:27:02 +00:00
< / CodeBlock >
2023-01-20 02:25:16 +00:00
When the build finishes, the terminal will display a URL like:
```
> Local: http://localhost:3000/
2023-05-01 01:27:02 +00:00
```
2023-01-20 02:25:16 +00:00
The server is listening on that URL. Open the link in a web browser.
3) Download < https: // sheetjs . com / pres . xlsx > and move to the `content` folder.
```bash
curl -L -o content/pres.xlsx https://sheetjs.com/pres.xlsx
```
2023-08-17 20:30:13 +00:00
4) Create the transformer. Two files must be saved at the root of the project:
2023-01-20 02:25:16 +00:00
2023-08-17 20:30:13 +00:00
- [`sheetformer.ts` ](https://docs.sheetjs.com/nuxt/3/sheetformer.ts ) (raw transformer module)
- [`sheetmodule.ts` ](https://docs.sheetjs.com/nuxt/3/sheetmodule.ts ) (Nuxt configuration module)
2023-01-20 02:25:16 +00:00
2023-08-17 20:30:13 +00:00
```bash
curl -O https://docs.sheetjs.com/nuxt/3/sheetformer.ts
curl -O https://docs.sheetjs.com/nuxt/3/sheetmodule.ts
2023-01-20 02:25:16 +00:00
```
After creating the source files, the module must be added to `nuxt.config.ts` :
```ts title="nuxt.config.ts"
import SheetJSModule from './sheetmodule'
export default defineNuxtConfig({
2023-06-02 02:17:56 +00:00
// @ts -ignore
telemetry: false,
2023-01-20 02:25:16 +00:00
modules: [
SheetJSModule,
'@nuxt/content'
],
content: {}
2023-08-17 20:30:13 +00:00
});
2023-01-20 02:25:16 +00:00
```
Restart the dev server by exiting the process (Control+C) and running:
```bash
2023-06-02 02:17:56 +00:00
npx -y nuxi clean
npx -y nuxi typecheck
npx -y yarn run dev
2023-01-20 02:25:16 +00:00
```
2023-05-03 03:40:40 +00:00
Loading `http://localhost:3000/pres` should show some JSON data:
2023-01-20 02:25:16 +00:00
```json
{
// ...
"data": {
"_path": "/pres",
// ...
"_id": "content:pres.xlsx",
"body": [
{
"name": "Sheet1", // < -- sheet name
"data": [ // < -- array of data objects
{
"Name": "Bill Clinton",
"Index": 42
},
```
2023-08-17 20:30:13 +00:00
5) Download [`pres.vue` ](pathname:///nuxt/3/pres.vue ) and save to `pages` :
2023-01-20 02:25:16 +00:00
2023-08-17 20:30:13 +00:00
```bash
curl -o pages/pres.vue https://docs.sheetjs.com/nuxt/3/pres.vue
2023-01-20 02:25:16 +00:00
```
Restart the dev server by exiting the process (Control+C) and running:
```bash
2023-06-02 02:17:56 +00:00
npx -y nuxi clean
npx -y yarn run dev
2023-01-20 02:25:16 +00:00
```
The browser should now display an HTML table.
6) To verify that hot loading works, open `pres.xlsx` from the `content` folder
in Excel. Add a new row to the bottom and save the file.
The page should automatically refresh with the new content.
7) Stop the server (press `CTRL+C` in the terminal window) and run
```bash
2023-06-02 02:17:56 +00:00
npx -y yarn run generate
2023-01-20 02:25:16 +00:00
```
This will create a static site in `.output/public` , which can be served with:
```bash
2023-06-02 02:17:56 +00:00
npx -y http-server .output/public
2023-01-20 02:25:16 +00:00
```
2023-05-03 03:40:40 +00:00
Accessing `http://localhost:8080/pres` will show the page contents. Verifying
2023-01-20 02:25:16 +00:00
the static nature is trivial: make another change in Excel and save. The page
will not change.
2023-08-17 20:30:13 +00:00
[^1]: See [`readFile` in "Reading Files" ](/docs/api/parse-options )
[^2]: See [`sheet_to_json` in "Utilities" ](/docs/api/utilities/array#array-output )
[^3]: See [`extendParser` ](https://content.nuxtjs.org/v1/getting-started/configuration#extendparser ) in the NuxtJS documentation.
[^4]: See ["Array of Objects" in the VueJS demo ](/docs/demos/frontend/vue#array-of-objects )
[^5]: See [`resolve` ](https://nodejs.org/api/path.html#pathresolvepaths ) in the NodeJS `node:path` documentation
[^6]: See [`readFileSync` ](https://nodejs.org/api/fs.html#fsreadfilesyncpath-options ) in the NodeJS `node:fs` documentation
[^7]: See [`read` in "Reading Files" ](/docs/api/parse-options )
[^8]: See [`sheet_to_json` in "Utilities" ](/docs/api/utilities/array#array-output )