diff --git a/docz/docs/03-demos/03-desktop/06-reactnative.md b/docz/docs/03-demos/03-desktop/06-reactnative.md index 4a97731..47313c0 100644 --- a/docz/docs/03-demos/03-desktop/06-reactnative.md +++ b/docz/docs/03-demos/03-desktop/06-reactnative.md @@ -214,10 +214,9 @@ been tested against both application types. :::caution -NodeJS `v16` is required. There are OS-specific tools for downgrading: - -- [`nvm-windows`](https://github.com/coreybutler/nvm-windows/releases) Windows -- [`n`](https://github.com/tj/n/) Linux, MacOS, WSL, etc. +At the time of testing, NodeJS `v16` was required. A tool like +[`nvm-windows`](https://github.com/coreybutler/nvm-windows/releases) should be +used to switch the NodeJS version. ::: @@ -436,10 +435,8 @@ This demo was tested against `v0.64.30` on 2023 January 04 in MacOS 12.4 :::caution -NodeJS `v16` is required. There are OS-specific tools for downgrading: - -- [`nvm-windows`](https://github.com/coreybutler/nvm-windows/releases) Windows -- [`n`](https://github.com/tj/n/) Linux, MacOS, WSL, etc. +At the time of testing, NodeJS `v16` was required. A tool like +[`n`](https://github.com/tj/n/) should be used to switch the NodeJS version. ::: diff --git a/docz/docs/03-demos/04-grid.md b/docz/docs/03-demos/05-grid.md similarity index 100% rename from docz/docs/03-demos/04-grid.md rename to docz/docs/03-demos/05-grid.md diff --git a/docz/docs/03-demos/05-database.md b/docz/docs/03-demos/06-database.md similarity index 100% rename from docz/docs/03-demos/05-database.md rename to docz/docs/03-demos/06-database.md diff --git a/docz/docs/03-demos/11-static/09-nuxtjs.md b/docz/docs/03-demos/11-static/09-nuxtjs.md index 0c5684f..b65e57e 100644 --- a/docz/docs/03-demos/11-static/09-nuxtjs.md +++ b/docz/docs/03-demos/11-static/09-nuxtjs.md @@ -4,17 +4,9 @@ pagination_prev: demos/extensions/index pagination_next: demos/gsheet --- -### NuxtJS - `@nuxt/content` is a file-based CMS for Nuxt, enabling static-site generation and on-demand server rendering powered by spreadsheets. -:::note - -This demo was tested on 2022 November 18 against Nuxt Content `v1.15.1`. - -::: - :::warning Nuxt Content `v2` (NuxtJS `v3`) employs a different architecture from `v1`. @@ -25,7 +17,15 @@ until the issues are resolved. ::: -## Configuration +## Nuxt Content v1 + +:::note + +This demo was tested on 2022 November 18 against Nuxt Content `v1.15.1`. + +::: + +### Configuration Through an override in `nuxt.config.js`, Nuxt Content will use custom parsers. Differences from a stock `create-nuxt-app` config are shown below: @@ -59,7 +59,7 @@ export default { } ``` -## Template Use +### Template Use 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 @@ -92,7 +92,7 @@ neatly with nested `v-for`: ``` -## Nuxt Content Demo +### Nuxt Content Demo :::note @@ -248,3 +248,235 @@ npx http-server dist Accessing the page http://localhost:8080 will show the page contents. Verifying the static nature is trivial: make another change in Excel and save. The page will not change. + +## Nuxt Content v2 + +:::note + +This demo was tested on 2023 January 19 against Nuxt Content `v2.3.0`. + +::: + +### Overview + +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 +`content` folder directly). This enables a transformer to re-read the file: + +```ts +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', + extensions: ['.xlsx'], + parse (_id: string, rawContent: string) { + const wb = read(readFileSync(resolve("./content/" + _id.slice(8)))); + const body = wb.SheetNames.map(name => ({ name, data: utils.sheet_to_json(wb.Sheets[name])})); + return { _id, body }; + } +}); +``` + +Pages can pull data using `useAsyncData`: + +```html + +``` + +Pages should use `ContentRenderer` to reference the data: + +```html + +``` + +### Nuxt Content 2 Demo + +:::note + +This demo was tested on 2023 January 19 against Nuxt Content `v2.3.0`. + +The generated project used Nuxt `v3.0.0`. + +::: + +1) Create a stock app and install dependencies: + +```bash +npx nuxi init -t content sheetjs-nc2 +cd sheetjs-nc2 +npx yarn install +``` + +2) Install the SheetJS library and start the server: + +```bash +npx yarn add https://cdn.sheetjs.com/xlsx-latest/xlsx-latest.tgz +npx yarn dev +``` + +When the build finishes, the terminal will display a URL like: + +``` + > Local: http://localhost:3000/ + ``` + +The server is listening on that URL. Open the link in a web browser. + +3) Download and move to the `content` folder. + +```bash +curl -L -o content/pres.xlsx https://sheetjs.com/pres.xlsx +``` + +4) Create the transformer. + +Two files must be written: + +- `sheetformer.ts` (the raw transformer module): + +```ts title="sheetformer.ts" +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', + extensions: ['.xlsx'], + parse (_id: string, rawContent: string) { + const wb = read(readFileSync(resolve("./content/" + _id.slice(8)))); + const body = wb.SheetNames.map(name => ({ name, data: utils.sheet_to_json(wb.Sheets[name])})); + return { _id, body }; + } +}); +``` + +- `sheetmodule.ts` (the nuxt configuration module): + +```ts title="sheetmodule.ts" +import { resolve } from 'path' +import { defineNuxtModule } from '@nuxt/kit' + +export default defineNuxtModule({ + setup (_options, nuxt) { + 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')) + // @ts-ignore + nuxt.hook('content:context', (contentContext) => { + contentContext.transformers.push(resolve('./sheetformer.ts')) + }) + } +}) +``` + +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({ + modules: [ + SheetJSModule, + '@nuxt/content' + ], + content: {} +}) +``` + +Restart the dev server by exiting the process (Control+C) and running: + +```bash +rm -rf .nuxt/content-cache ## forcefully clear cache +npx yarn run dev +``` + +Loading http://localhost:3000/pres should show some JSON data: + +```json +{ + // ... + "data": { + "_path": "/pres", + // ... + "_id": "content:pres.xlsx", + "body": [ + { + "name": "Sheet1", // <-- sheet name + "data": [ // <-- array of data objects + { + "Name": "Bill Clinton", + "Index": 42 + }, +``` + +5) Create a page. Save the following content to `pages/pres.vue`: + +```html + + +``` + +Restart the dev server by exiting the process (Control+C) and running: + +```bash +rm -rf .nuxt/content-cache ## forcefully clear cache +npx yarn run dev +``` + +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 +npx yarn run generate +``` + +This will create a static site in `.output/public`, which can be served with: + +```bash +npx http-server .output/public +``` + +Accessing http://localhost:8080/pres will show the page contents. Verifying +the static nature is trivial: make another change in Excel and save. The page +will not change.