diff --git a/docz/docs/02-getting-started/02-example.mdx b/docz/docs/02-getting-started/02-example.mdx
index b58bf64..0c6dcc9 100644
--- a/docz/docs/02-getting-started/02-example.mdx
+++ b/docz/docs/02-getting-started/02-example.mdx
@@ -6,6 +6,7 @@ sidebar_position: 2
import current from '/version.js';
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
+import CodeBlock from '@theme/CodeBlock';
# Tutorial
diff --git a/docz/docs/03-demos/01-frontend/04-svelte.md b/docz/docs/03-demos/01-frontend/04-svelte.md
index a74219d..533fb93 100644
--- a/docz/docs/03-demos/01-frontend/04-svelte.md
+++ b/docz/docs/03-demos/01-frontend/04-svelte.md
@@ -14,6 +14,7 @@ familiarity is assumed.
Other demos cover general Svelte deployments, including:
+- [Static Site Generation powered by SvelteKit](/docs/demos/static/svelte)
- [iOS applications powered by CapacitorJS](/docs/demos/mobile/capacitor)
- [Desktop application powered by Wails](/docs/demos/desktop/wails)
diff --git a/docz/docs/03-demos/04-static/05-vitejs.md b/docz/docs/03-demos/04-static/05-vitejs.md
index f0b1980..c22ecc4 100644
--- a/docz/docs/03-demos/04-static/05-vitejs.md
+++ b/docz/docs/03-demos/04-static/05-vitejs.md
@@ -7,6 +7,7 @@ sidebar_custom_props:
---
import current from '/version.js';
+import CodeBlock from '@theme/CodeBlock';
:::note
@@ -28,7 +29,8 @@ recommended. The heavy work is performed at build time and the generated site
only includes the raw data.
For more complex parsing or display logic, ["Base64 Loader"](#base64-loader) is
-preferable. Since the raw parsing logic is performed in the page,
+preferable. Since the raw parsing logic is performed in the page, the library
+will be included in the final bundle.
:::
@@ -119,20 +121,20 @@ ${csv}
:::note
-This demo was tested on 2023 January 14 against `vite v4.0.4`.
+This demo was tested on 2023 April 30 against `vite v4.3.3`.
:::
### Initial Setup
-1) Create a new site using the `vue-ts` template:
+1) Create a new site with the `vue-ts` template and install the SheetJS package:
-```bash
+{`\
npm create vite@latest sheetjs-vite -- --template vue-ts
cd sheetjs-vite
npm install
-npm i --save https://cdn.sheetjs.com/xlsx-latest/xlsx-latest.tgz
-```
+npm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz`}
+
2) Replace `vite.config.ts` with the following:
@@ -214,7 +216,7 @@ npm run build
npx http-server dist/
```
-The terminal will display a url like http://127.0.0.1:8080. Access that page
+The terminal will display a url like `http://127.0.0.1:8080` . Access that page
with a web browser.
7) To confirm that only the raw data is present in the page, view the page
diff --git a/docz/docs/03-demos/04-static/11-svelte.md b/docz/docs/03-demos/04-static/11-svelte.md
new file mode 100644
index 0000000..c8c2138
--- /dev/null
+++ b/docz/docs/03-demos/04-static/11-svelte.md
@@ -0,0 +1,237 @@
+---
+title: SvelteKit
+pagination_prev: demos/net/index
+pagination_next: demos/mobile/index
+---
+
+import current from '/version.js';
+
+:::note
+
+This demo covers SvelteKit. The [Svelte demo](/docs/demos/frontend/svelte)
+covers general client-side strategies.
+
+This demo uses ["Base64 Loader"](/docs/demos/static/vitejs#base64-loader)
+from the ViteJS demo.
+
+:::
+
+SvelteKit projects use ViteJS under the hood. They expose the `vite.config.js`
+script. The [ViteJS demo](/docs/demos/static/vitejs) examples work as expected!
+
+The following diagram depicts the workbook waltz:
+
+```mermaid
+flowchart LR
+ file[(workbook\nfile)]
+ subgraph SheetJS operations
+ base64(base64\nstring)
+ aoa(array of\nobjects)
+ end
+ html{{HTML\nTABLE}}
+ file --> |vite.config.js\ndata loader| base64
+ base64 --> |+page.server.js\nload function| aoa
+ aoa --> |+page.svelte\ncomponent| html
+```
+
+## Integration
+
+`+page.server.js` scripts can be pre-rendered by exporting `prerender` from the
+script. If the SheetJS operations are performed in the server script, only the
+results will be added to the generated pages!
+
+For static site generation, `@sveltejs/adapter-static` must be used.
+
+### Loader
+
+:::note
+
+The ViteJS demo used the query `?b64` to identify files. To play nice with
+SvelteKit, this demo matches the file extensions directly.
+
+:::
+
+The loader should be added to `vite.config.js`. The code is nearly identical to
+the ["Base64 Loader" ViteJS example.](/docs/demos/static/vitejs#base64-loader)
+
+```js title="vite.config.js"
+import { sveltekit } from '@sveltejs/kit/vite';
+import { defineConfig } from 'vite';
+import { readFileSync } from 'fs';
+
+export default defineConfig({
+ assetsInclude: ['**/*.numbers', '**/*.xlsx'],
+ plugins: [sveltekit(), {
+ name: "sheet-base64",
+ transform(code, id) {
+ if(!id.match(/\.(numbers|xlsx)$/)) return;
+ var data = readFileSync(id, "base64");
+ return `export default '${data}'`;
+ }
+ }]
+});
+```
+
+#### Types
+
+For VSCodium integration, types can be specified in `src/app.d.ts`.
+
+The example data loader returns Base64 strings. Declarations should be added for
+each file extension supported in the loader:
+
+```ts title="src/app.d.ts"
+declare global {
+ declare module '*.numbers' {
+ const data: string;
+ export default data;
+ }
+ declare module '*.xlsx' {
+ const data: string;
+ export default data;
+ }
+}
+```
+
+### Data Processing
+
+For static sites, SheetJS operations should be run in `+page.server.js` .
+
+Assuming `pres.xlsx` is stored in the `data` directory from the project root,
+the relative import
+
+```js
+import b64 from "../../data/pres.xlsx"
+```
+
+will return a Base64 string which can be parsed in the script. The workbook
+object can be post-processed using utility functions. The following example
+uses `sheet_to_json` to generate arrays of row objects for each worksheet. The
+data presented to the page will be an object whose keys are worksheet names:
+
+```js title="src/routes/+page.server.js"
+import b64 from "../../data/pres.xlsx";
+import { read, utils } from "xlsx";
+
+export const prerender = true;
+
+/** @type {import('./$types').PageServerLoad} */
+export async function load({ params }) {
+ const wb = read(b64);
+ /** @type {[string, any[]][]} */
+ const data = wb.SheetNames.map(n => [n, utils.sheet_to_json(wb.Sheets[n])]);
+ return Object.fromEntries(data);
+}
+```
+
+### Data Rendering
+
+The shape of the data is determined by the loader. The example loader returns an
+object whose keys are worksheet names and whose values are arrays of objects.
+
+Using standard Svelte patterns, HTML tables can be generated from the data:
+
+```html title="src/routes/+page.svelte"
+
+
+
Presidents
+Name | Index |
+ {#each pres as p}
+ {p.Name} |
+ {p.Index} |
+
{/each}
+
+```
+
+When built using `npm run build`, SvelteKit will perform the conversion and emit
+a simple HTML table without any reference to the existing spreadsheet file!
+
+## Complete Example
+
+:::note
+
+This demo was tested on 2023 April 30 using SvelteKit `1.15.9`
+
+:::
+
+### Initial Setup
+
+1) Create a new site:
+
+```bash
+npm create svelte@latest sheetjs-svelte
+cd sheetjs-svelte
+npm i
+```
+
+2) Fetch the example file [`pres.xlsx`](https://sheetjs.com/pres.xlsx) and move
+to a `data` subdirectory in the root of the project:
+
+```bash
+mkdir -p data
+curl -Lo data/pres.xlsx https://sheetjs.com/pres.xlsx
+```
+
+3) Install the SheetJS library:
+
+{`\
+npm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz`}
+
+
+4) Replace the contents of `vite.config.js` with the contents of the code block
+named [`vite.config.js` in the "Loader" section](#loader)
+
+5) Append the lines from [`src/app.d.ts` snippet in the "Types" section](#types)
+to the `src/app.d.ts` file.
+
+6) Replace the contents of `src/routes/+page.server.ts` with the contents of the
+code block named [`src/routes/+page.server.ts` in "Data Processing"](#data-processing)
+
+7) Replace the contents of `src/routes/+page.svelte` with the contents of the
+code block named [`src/routes/+page.svelte` in "Data Rendering"](#data-rendering)
+
+### Live Reload
+
+8) Open `data/pres.xlsx` in a spreadsheet editor like Apple Numbers or Excel.
+
+9) Start the development server:
+
+```bash
+npm run dev
+```
+
+Open the displayed URL (typically `http://localhost:5173`) in a web browser and
+observe that the data from the spreadsheet is displayed in the page.
+
+10) In the spreadsheet, set cell A7 to `SheetJS Dev` and cell B7 to `47`. Save
+the file. After saving, the browser should automatically refresh with new data.
+
+### Static Site
+
+11) Stop the development server and install the static adapter:
+
+```bash
+npm install --save @sveltejs/adapter-static
+```
+
+12) Edit `svelte.config.js` to use the new adapter:
+
+```diff title="svelte.config.js"
+-import adapter from '@sveltejs/adapter-auto';
++import adapter from '@sveltejs/adapter-static';
+```
+
+13) Build the static site:
+
+```bash
+npm run build
+```
+
+14) Open a web browser and access the displayed URL (`http://localhost:8080`).
+View the page source and confirm that the raw HTML table includes the data.
\ No newline at end of file
diff --git a/docz/docs/03-demos/06-desktop/03-wails.md b/docz/docs/03-demos/06-desktop/03-wails.md
index e740eaa..d07db88 100644
--- a/docz/docs/03-demos/06-desktop/03-wails.md
+++ b/docz/docs/03-demos/06-desktop/03-wails.md
@@ -10,6 +10,7 @@ sidebar_custom_props:
import current from '/version.js';
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
+import CodeBlock from '@theme/CodeBlock';
The [NodeJS Module](/docs/getting-started/installation/nodejs) can be imported
from JavaScript code.
@@ -233,7 +234,7 @@ async function exportFile(wb) {
:::note
-This demo was tested against Wails `v2.4.0` on 2023 March 18 using
+This demo was tested against Wails `v2.4.1` on 2023 April 30 using
the Svelte TypeScript starter.
:::
@@ -254,12 +255,12 @@ cd sheetjs-wails
3) Install front-end dependencies:
-```bash
+{`\
cd frontend
curl -L -o src/assets/logo.png https://sheetjs.com/sketch1024.png
-npm i --save https://cdn.sheetjs.com/xlsx-latest/xlsx-latest.tgz
-cd ..
-```
+npm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz
+cd ..`}
+
4) Download source files:
diff --git a/docz/docs/03-demos/10-extensions/01-extendscript.md b/docz/docs/03-demos/10-extensions/01-extendscript.md
index 59dbfc5..9aba951 100644
--- a/docz/docs/03-demos/10-extensions/01-extendscript.md
+++ b/docz/docs/03-demos/10-extensions/01-extendscript.md
@@ -29,7 +29,7 @@ This demo was verified in the following deployments:
|:----------|:-------------|:-----------|
| Photoshop | ExtendScript | 2023-04-15 |
| InDesign | ExtendScript | 2023-04-15 |
-| InDesign | CEP | 2023-04-24 |
+| InDesign | CEP | 2023-04-30 |
| InDesign | UXP | 2023-04-15 |
:::
@@ -242,8 +242,11 @@ const wb = XLSX.read(data.data, { type: "base64" });
0) Download [`com.sheetjs.data.zip`](pathname:///extendscript/com.sheetjs.data.zip)
and extract to a `com.sheetjs.data` subdirectory.
-1) Move the entire `com.sheetjs.data` folder to the CEP extensions folder. In
-Windows, the folder is `C:\Program Files (x86)\Common Files\Adobe\CEP\extensions\` .
+1) Move the entire `com.sheetjs.data` folder to the CEP extensions folder:
+
+- Windows `C:\Program Files (x86)\Common Files\Adobe\CEP\extensions\`
+- Macintosh `/Library/Application\ Support/Adobe/CEP/extensions`
+
If prompted, give administrator privileges.
2) Download and open [`Template.idml`](pathname:///extendscript/Template.idml)
@@ -285,8 +288,11 @@ cep.fs.writeFile(fn.data, b64, cep.encoding.Base64);
0) Download [`com.sheetjs.data.zip`](pathname:///extendscript/com.sheetjs.data.zip)
and extract to a `com.sheetjs.data` subdirectory.
-1) Move the entire `com.sheetjs.data` folder to the CEP extensions folder. In
-Windows, the folder is `C:\Program Files (x86)\Common Files\Adobe\CEP\extensions\` .
+1) Move the entire `com.sheetjs.data` folder to the CEP extensions folder:
+
+- Windows `C:\Program Files (x86)\Common Files\Adobe\CEP\extensions\`
+- Macintosh `/Library/Application\ Support/Adobe/CEP/extensions`
+
If prompted, give administrator privileges.
2) Download and open [`Filled.idml`](pathname:///extendscript/Filled.idml)
@@ -317,7 +323,7 @@ const storage = require("uxp").storage;
const ufs = storage.localFileSystem;
```
-**Reading Files**
+### Reading Files
The `getFileForOpening` method resolves to a `File` object. Reading the file
with the `binary` format returns an `ArrayBuffer` object that can be parsed:
@@ -331,7 +337,7 @@ const ab = await file.read({ format: storage.formats.binary });
const wb = XLSX.read(ab);
```
-**Writing Files**
+### Writing Files
The `getFileForSaving` method resolves to a `File` object. The workbook should
be written with `type: "buffer"` for compatibility with the `binary` format:
diff --git a/docz/docs/03-demos/index.md b/docz/docs/03-demos/index.md
index 00ccea6..9179384 100644
--- a/docz/docs/03-demos/index.md
+++ b/docz/docs/03-demos/index.md
@@ -64,6 +64,7 @@ run in the web browser, demos will include interactive examples.
- [`ViteJS`](/docs/demos/static/vitejs)
- [`NextJS`](/docs/demos/static/nextjs)
- [`NuxtJS`](/docs/demos/static/nuxtjs)
+- [`SvelteKit`](/docs/demos/static/svelte)
### App Extensions
diff --git a/docz/static/extendscript/com.sheetjs.data.zip b/docz/static/extendscript/com.sheetjs.data.zip
index a1f2bac..423bcb7 100644
Binary files a/docz/static/extendscript/com.sheetjs.data.zip and b/docz/static/extendscript/com.sheetjs.data.zip differ