2023-05-07 13:58:36 +00:00
---
title: Eleventy
pagination_prev: demos/net/index
pagination_next: demos/mobile/index
---
import current from '/version.js';
2023-12-05 03:46:54 +00:00
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
2023-05-07 13:58:36 +00:00
import CodeBlock from '@theme/CodeBlock';
2023-10-09 01:13:21 +00:00
[Eleventy ](https://www.11ty.dev/docs ) is a telemetry-free static site generator.
The data pipeline can be augmented with custom data file parsers.
2023-05-07 13:58:36 +00:00
2023-10-09 01:13:21 +00:00
[SheetJS ](https://sheetjs.com ) is a JavaScript library for reading and writing
data from spreadsheets.
This demo uses Eleventy and SheetJS to pull data from a spreadsheet and display
the content in a page. We'll explore how to load SheetJS libraries in a custom
data file format parser and generate arrays of objects for use in pages.
2023-05-07 13:58:36 +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 --> |.eleventy.js\ncustom parser| buffer
buffer --> |.eleventy.js\ncustom parser| aoo
aoo --> |index.njk\ntemplate| html
```
2023-10-09 01:13:21 +00:00
:::tip No Telemetry
The author has publicly stated that Eleventy does not embed any telemetry or
data collection.[^1]
:::
2023-05-07 13:58:36 +00:00
## Integration Details
2023-10-09 01:13:21 +00:00
The [SheetJS NodeJS module ](/docs/getting-started/installation/nodejs ) can be
loaded in `.eleventy.js` and used in custom data file format parsers.
2023-05-07 13:58:36 +00:00
### Data File Parser
Custom data file parsers must be registered in `.eleventy.js`
2023-10-09 01:13:21 +00:00
The Eleventy config `addDataExtension` method[^2] accepts a list of file
extensions and a parser configuration object.
2023-05-07 13:58:36 +00:00
The parser object must include the options `read: true` and `encoding: null` .
Eleventy will read files and pass raw `Buffer` objects to the parser callback.
2023-10-09 01:13:21 +00:00
The `parser` callback can parse the raw `Buffer` data with the SheetJS `read`
method[^3]. The method returns a workbook object[^4].
In this example, the parser will use the SheetJS `sheet_to_json` method[^5] to
generate an array of objects from the data in the first worksheet:
2023-05-07 13:58:36 +00:00
```js title=".eleventy.js"
const XLSX = require("xlsx");
/* list of file extensions */
const exts = [ "numbers", "xlsx", "xlsb", "xls" ].join(", ");
module.exports = (eleventyConfig) => {
eleventyConfig.addDataExtension(exts, {
/* read file and pass raw Buffer object to parser */
// highlight-next-line
encoding: null, read: true,
/* parser callback */
parser: (contents) => {
/* contents is the data stored as a Buffer */
// highlight-next-line
const wb = XLSX.read(contents);
/* generate array of row objects from first worksheet */
return XLSX.utils.sheet_to_json(wb.Sheets[wb.SheetNames[0]]);
}
});
};
```
### Usage
Spreadsheet files added in the `_data` subdirectory are accessible from template
files using the name stem.
For example, [`pres.numbers` ](https://sheetjs.com/pres.numbers ) can be accessed
using the variable `pres` in a template:
```liquid title="index.njk"
2023-12-05 03:46:54 +00:00
< table > < thead > < tr > < th > Name< / th > < th > Index< / th > < / tr > < / thead >
2023-05-07 13:58:36 +00:00
< tbody >
{% for row in pres %}
< tr >
< td > {{ row.Name }}< / td >
< td > {{ row.Index }}< / td >
< / tr >
{% endfor %}
< / tbody >
< / table >
```
## Complete Example
2023-12-05 03:46:54 +00:00
:::note Tested Deployments
2023-05-07 13:58:36 +00:00
2023-12-05 03:46:54 +00:00
This demo was tested in the following environments:
| Eleventy | Date |
|:----------------|:-----------|
2024-03-16 16:04:18 +00:00
| `2.0.1` | 2024-03-15 |
| `3.0.0-alpha.5` | 2024-03-15 |
2023-05-07 13:58:36 +00:00
:::
### Project Setup
1) Create a new project:
```bash
mkdir sheetjs-11ty
cd sheetjs-11ty
npm init -y
```
2) Install Eleventy and SheetJS libraries:
2023-12-05 03:46:54 +00:00
< Tabs groupId = "11ty" >
< TabItem value = "2" label = "Stable" >
2023-05-07 13:58:36 +00:00
< CodeBlock language = "bash" > {`\
2024-03-16 16:04:18 +00:00
npm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz @11ty/eleventy@2 .0.1`}
2023-05-07 13:58:36 +00:00
< / CodeBlock >
2023-12-05 03:46:54 +00:00
< / TabItem >
< TabItem value = "3" label = "Alpha" >
< CodeBlock language = "bash" > {`\
2024-03-16 16:04:18 +00:00
npm i --save https://cdn.sheetjs.com/xlsx-${current}/xlsx-${current}.tgz @11ty/eleventy@3 .0.0-alpha.5`}
2023-12-05 03:46:54 +00:00
< / CodeBlock >
< / TabItem >
< / Tabs >
2023-05-07 13:58:36 +00:00
3) Make a new `_data` subdirectory in the project. Download the example file
[`pres.xlsx` ](https://sheetjs.com/pres.xlsx ) into `_data` :
```bash
mkdir _data
curl -Lo _data/pres.xlsx https://sheetjs.com/pres.xlsx
```
4) Download the following files to the project folder:
- [`_eleventy.js` ](pathname:///eleventy/_eleventy.js ) (rename to `.eleventy.js` )
- [`index.njk` ](pathname:///eleventy/index.njk )
```bash
curl -L -o .eleventy.js https://docs.sheetjs.com/eleventy/_eleventy.js
curl -LO https://docs.sheetjs.com/eleventy/index.njk
```
### Live Reload
5) Start the live reloading server:
```bash
npx @11ty/eleventy --serve
```
The server will generate `index.html` from `index.njk` and show the server URL:
```
[11ty] Writing _site/index.html from ./index.njk
[11ty] Wrote 1 file in 0.23 seconds (v2.0.1)
[11ty] Watching…
[11ty] Server at http://localhost:8080/ < -- this is the URL
```
6) Open the URL in a web browser. The page should include a table.
2024-03-16 16:04:18 +00:00
7) Open `_data/pres.xlsx` in a spreadsheet editor. Add a row to the bottom of
the "Sheet1" sheet (set `A7` to "SheetJS Dev" and `B7` to `47` ). Save the file.
2023-05-07 13:58:36 +00:00
The server log will note that the file changed:
```
[11ty] File changed: _data/pres.xlsx
[11ty] Writing _site/index.html from ./index.njk
```
The browser will refresh to show the new data.
### Static Site
8) Stop the live reload server and build the static site:
```bash
npx @11ty/eleventy
```
Eleventy will place the generated site in the `_site` subfolder.
9) Start a web server to host the static site:
```bash
npx http-server _site
```
Open a web browser and access the displayed URL ( `http://localhost:8080` ).
View the page source and confirm that no JS was added to the page. It only
contains the content from the file in an HTML table.
2023-10-09 01:13:21 +00:00
[^1]: See [the "Telemetry" section ](https://www.zachleat.com/web/site-generator-review/#telemetry ) of the site generator review from the author of Eleventy. When this page was last checked, the author proudly asserted that Eleventy had "No known Telemetry or data collection".
[^2]: See ["Custom Data File Formats" ](https://www.11ty.dev/docs/data-custom/ ) in the Eleventy documentation.
[^3]: See [`read` in "Reading Files" ](/docs/api/parse-options )
[^4]: See ["Workbook Object" ](/docs/csf/book ) for more details on the SheetJS workbook object.
[^5]: See [`sheet_to_json` in "Utilities" ](/docs/api/utilities/array#array-output )