diff --git a/docz/docs/03-demos/30-cloud/03-oraclecloud.md b/docz/docs/03-demos/30-cloud/03-oraclecloud.md
new file mode 100644
index 0000000..b1d315d
--- /dev/null
+++ b/docz/docs/03-demos/30-cloud/03-oraclecloud.md
@@ -0,0 +1,541 @@
+---
+title: Oracle Cloud Services
+pagination_prev: demos/local/index
+pagination_next: demos/extensions/index
+---
+
+import current from '/version.js';
+import CodeBlock from '@theme/CodeBlock';
+
+[Oracle Cloud Services](https://www.oracle.com/cloud/) (OCI) is a cloud services
+platform which includes traditional virtual machine support, "Serverless
+Functions" and cloud storage.
+
+[SheetJS](https://sheetjs.com) is a JavaScript library for reading and writing
+data from spreadsheets.
+
+This demo demonstrates how to integrate SheetJS with Oracle `Visual Builder Studio (VBS)`[^2]
+to build a web application that handles Excel files. You'll learn to create an application
+that can import spreadsheet data, store it in `Business Objects`[^1], display it in a table, and
+export it back to Excel format.
+
+:::caution pass
+
+Oracle Cloud Services iterates quickly and there is no guarantee that the referenced services
+will be available in the future.
+
+:::
+
+:::note Tested Deployments
+
+This demo was last tested on 2025-02-04.
+
+:::
+
+
+## Visual Applications
+Oracle Cloud Services offers Visual Builder Studio a browser-based development environment for
+creating web applications with drag-and-drop components.
+
+
+## Installation
+SheetJS libraries conform to the Oracle Cloud Visual Builder Studio (VBS) ECMAScript[^5] requirements.
+SheetJS libraries can be loaded in Oracle VBS site at different points in the app lifecycle.
+
+#### Configure in app-flow.json
+
+The `app-flow.json` method is recommended as it aligns better with Visual Builder Studio's
+module management system.
+
+1. Click 📄 `Source` from the left sidebar
+2. Open `webApps/sheetjs_demo_app/app-flow.json`
+3. Add the following configuration after line 5:
+
+{`\
+"requirejs": {
+ "paths": {
+ "xlsx": "https://cdn.sheetjs.com/xlsx-${current}/package/dist/xlsx.full.min.js"
+ }
+ }
+`}
+
+
+#### HTML {#installation-html}
+
+Oracle Cloud VBS is typically loaded in `SCRIPT` tag in `webApps/sheetjs_demo_app/index.html`. Similarly,
+[SheetJS Standalone scripts](/docs/getting-started/installation/standalone)
+can be loaded with a `SCRIPT` tag in the same HTML page:
+
+{`\
+
+`}
+
+
+This will expose the `XLSX` global object, which includes the functions listed
+in the ["API Reference"](/docs/api/) section of the documentation.
+
+
+## Internal State
+
+The various SheetJS APIs work with various data shapes. The preferred state
+depends on the application.
+
+
+### Business Objects
+
+`Business Objects`[^1] in Oracle VBS provides a server-side model implementation for persistent data storage.
+Think of them as a combination of a data model and database table that handles both data storage and
+UI binding.
+
+#### Business Object Definition
+
+The example [presidents sheet](https://docs.sheetjs.com/pres.xlsx) has one header row with "Name" and "Index"
+columns. In Oracle VBS, we model this as a Business Object with corresponding fields:
+
+
+ Spreadsheet | Business Object Definition |
+
+
+![`pres.xlsx` data](pathname:///pres.png)
+
+ |
+
+```json
+{
+ "items" : [ {
+ "name": "Pres",
+ "fields": {
+ "name": {
+ "type": "string",
+ "label": "Name"
+ },
+ "index1": {
+ "type": "number",
+ "label": "Index"
+ }
+ }
+ }]
+}
+```
+
+ |
+
+Here is how the data is represented when queried from the Business Object via REST call:
+
+```json
+{
+ "items": [
+ { "name": "Bill Clinton", "index1": 42 },
+ { "name": "GeorgeW Bush", "index1": 43 },
+ { "name": "Barack Obama", "index1": 44 },
+ { "name": "Donald Trump", "index1": 45 },
+ { "name": "Joseph Biden", "index1": 46 }
+ ]
+}
+```
+
+#### Updating Business Object
+
+Starting from a spreadsheet file, the SheetJS [`read`](/docs/api/parse-options) method parses the data into a workbook object. After
+selecting a worksheet, [`sheet_to_json`](/docs/api/utilities/array#array-output) generates row objects that can be created as Business Object
+records using the auto-generated REST API.
+
+Here is a sample flow diagram and method for downloading a workbook, generating rows from the first worksheet, and updating a `Business Object`[^1]:
+
+```mermaid
+flowchart LR
+ xlsx[(Remote\nFile)]
+ bo1[(Data\nArrayBuffer)]
+ wb(SheetJS\nWorkbook)
+ ws(SheetJS\nWorksheet)
+ json(JSON\nData)
+ bo2[(Business\nObject)]
+
+ xlsx --> |fetch\n\n| bo1
+ bo1 --> |XLSX.read\n\n| wb
+ wb --> |wb.Sheets\nselect| ws
+ ws --> |sheet_to_json\n\n| json
+ json --> |REST API\ncreate| bo2
+ linkStyle 1,2,3 color:blue,stroke:blue;
+```
+
+{`
+ define(['vb/action/actionChain', 'vb/action/actions', 'xlsx'], (ActionChain, Actions, XLSX) => {
+ class ButtonActionChain extends ActionChain {
+ async run(context) {
+ // fetch XLSX file
+ const data = await (await fetch("https://docs.sheetjs.com/pres.xlsx")).arrayBuffer();
+ const wb = XLSX.read(data);
+ // get the first worksheet
+ const ws = wb.Sheets[wb.SheetNames[0]];
+ // convert to json
+ const jsonData = XLSX.utils.sheet_to_json(ws);
+
+ // process each row and create business object records
+ for (const row of jsonData) {
+ const presData = {
+ name: row.Name,
+ index1: Number(row.Index)
+ };
+
+ // update business object with new record
+ await Actions.callRest(context, {
+ endpoint: 'businessObjects/create_Pres',
+ body: presData
+ });
+ }
+ }
+ }
+ return ButtonActionChain;
+ });
+`}
+
+
+#### Rendering Data
+In Oracle VBS, the table component `oj-table` supports direct binding to Business Objects for data display.
+The view structure defines both the data source binding and column layout:
+
+The following example uses the `Table`[^4] component to display data.
+
+{`\
+
+ // highlight-start
+
+
+
+ // highlight-end
+
+`}
+
+
+
+#### Exporting Data
+The export functionality converts Business Object data into an Excel spreadsheet. The process involves retrieving data through
+REST API call, transforming it into a format suitable for SheetJS, and generating an XLSX file. Here's the complete flow:
+
+```mermaid
+flowchart LR
+ bo[(Business\nObject)]
+ rest(REST API\nCall)
+ json(JSON\nArray)
+ ws(SheetJS\nWorksheet)
+ wb(SheetJS\nWorkbook)
+ xlsx[(XLSX\nFile)]
+
+ bo --> |getall_Pres\nendpoint| rest
+ rest --> |transform\nresponse| json
+ json --> |json_to_sheet\n\n| ws
+ ws --> |book_new\n\n| wb
+ wb --> |writeFileXLSX\n\n| xlsx
+
+ linkStyle 2,3,4 color:blue,stroke:blue;
+```
+
+{`
+ define(['vb/action/actionChain', 'vb/action/actions', 'xlsx'], (ActionChain, Actions, XLSX) => {
+ class ButtonActionChain1 extends ActionChain {
+ async run(context) {
+ // get pres data
+ const presDataResponse = await Actions.callRest(context, {
+ endpoint: 'businessObjects/getall_Pres',
+ parameters: {
+ fields: 'name,index1'
+ }
+ });
+
+ // transform to simple array
+ const simplifiedData = presDataResponse.body.items.map(item => ({
+ Name: item.name,
+ Index: item.index1
+ }));
+
+ // generate workbook
+ const ws = XLSX.utils.json_to_sheet(simplifiedData);
+ const wb = XLSX.utils.book_new(ws, "Presidents");
+
+ // export to XLSX which triggers a download
+ XLSX.writeFileXLSX(wb, "SheetJSOracleVisualBuilderAoO.xlsx");
+ }
+ }
+ return ButtonActionChain1;
+ });
+`}
+
+
+:::note pass
+
+Visual Builder Studio provides a visual development environment and handles the build and
+deployment process automatically.
+
+:::
+
+
+## Importing Data {#importing-data-snippet}
+The import functionality enables data transfer from an Excel spreadsheet into your Oracle VBS
+application. The process begins by fetching the XLSX file, parsing it using SheetJS, and then
+creating corresponding Business Object records.
+
+```javascript title=""
+define([
+ 'vb/action/actionChain',
+ 'vb/action/actions',
+ 'vb/action/actionUtils',
+ 'xlsx'
+], (
+ ActionChain,
+ Actions,
+ ActionUtils,
+ XLSX
+) => {
+ 'use strict';
+
+ class ButtonActionChain extends ActionChain {
+
+ /**
+ * @param {Object} context
+ */
+ async run(context) {
+ const { $page, $flow, $application, $constants, $variables } = context;
+
+ // fetch XLSX file
+ const url = "https://docs.sheetjs.com/pres.xlsx";
+ const data = await (await fetch(url)).arrayBuffer();
+ const wb = XLSX.read(data);
+
+ // get the first worksheet
+ const ws = wb.Sheets[wb.SheetNames[0]];
+
+ // convert to json
+ const jsonData = XLSX.utils.sheet_to_json(ws);
+
+ // process each row and create business object records
+ for (const row of jsonData) {
+ const presData = {
+ name: row.Name,
+ index1: Number(row.Index)
+ };
+
+ // create a business object record
+ await Actions.callRest(context, {
+ endpoint: 'businessObjects/create_Pres',
+ body: presData
+ });
+ }
+ }
+ }
+ return ButtonActionChain;
+});
+```
+
+## Exporting Data {#exporting-data-snippet}
+The export functionality allows you to convert Business Object data into Excel spreadsheets.
+This process involves retrieving data from the Business Object using REST API calls, transforming
+it into a format suitable for SheetJS, and generating an XLSX file.
+
+```javascript
+define([
+ 'vb/action/actionChain',
+ 'vb/action/actions',
+ 'vb/action/actionUtils',
+ 'xlsx'
+], (
+ ActionChain,
+ Actions,
+ ActionUtils,
+ XLSX
+) => {
+ 'use strict';
+
+ class ButtonActionChain1 extends ActionChain {
+
+ /**
+ * @param {Object} context
+ */
+ async run(context) {
+ const { $page, $flow, $application, $constants, $variables } = context;
+
+ // get pres data
+ const presDataResponse = await Actions.callRest(context, {
+ endpoint: 'businessObjects/getall_Pres',
+ parameters: {
+ fields: 'name,index1'
+ }
+ });
+
+ // transform to simple array
+ const simplifiedData = presDataResponse.body.items.map(item => ({
+ Name: item.name,
+ Index: item.index1
+ }));
+
+ // generate workbook
+ const ws = XLSX.utils.json_to_sheet(simplifiedData);
+ const wb = XLSX.utils.book_new(ws, "Presidents");
+
+ /* export to XLSX */
+ XLSX.writeFileXLSX(wb, "SheetJSOracleVisualBuilderAoO.xlsx");
+
+ }
+ }
+ return ButtonActionChain1;
+});
+```
+
+## Oracle Visual Builder Studio Web Applications Demo
+
+:::note pass
+
+At the time of writing, Oracle Cloud offers a 30-day free trial that includes
+Visual Builder Studio access.
+
+:::
+
+0. If you do not have an account create a new Oracle Cloud free tier account[^3].
+
+### Visual Builder Setup
+
+1. Sign in to the [Oracle Cloud Management Console](https://cloud.oracle.com/) with your created account.
+
+2. Type "Visual Builder Studio" in the top search box and click Visual Builder Studio (under services).
+
+![Oracle Cloud search for "Visual Builder Studio"](pathname:///oraclecloud/search_box_visual_builder.png)
+
+3. Before creating Visual Builder Studio Instances we need to create an instance. Click `Visual Builder` from the left sidebar and click Create an instance.
+
+![Create Visual Builder Instance](pathname:///oraclecloud/create_vb_instance.png)
+
+- Give it a name: `sheetjs-demo-vb-instance`
+- Select network access: `Default (No access rules.)`
+- Nodes: `1`
+
+4. Now click `Visual Builder Studio` from the left sidebar and click `Create Visual Builder Studio` and give it instance name: `sheetjs-vbs-instance` and click next and set
+ select compartment to `yourusername (root)`. Lastly, click `Create Visual Builder Studio` (this will take 5-15 minutes to fully setup).
+
+- Click link name `sheetjs-vbs-instance`
+
+5. Click `Service Console` create a new project and fill it with the following inputs.
+
+- Project Details: `sheetjs-demo-project`
+- Project Template: `Empty Project`
+- Project Properties: `Markdown`
+- Click Finish
+
+6. Select `Project Home` from the left sidebar and create an environment.
+- Environment Name: `sheetjs-demo-env`
+- Click Create
+- Click `Add Instance`
+
+![Connect instance to environment](pathname:///oraclecloud/env_connect_to_instance.png)
+
+7. In Environments select the Service Instances tab and search for `Instance URL` if not shown click details to expand Visual Builder `sheetjs-demo-vb-instance` and open `Instance URL`
+ This will open Visual Builder Studio.
+
+8. Click `New Application` and set
+
+- Application Display Name: `sheetjs-vbs-demo`
+- Application Template: `Empty Application`
+- Click Finish
+
+9. Create a new Business Object by clicking **Business Object** card in the Welcome tab or from the sidebar as shown
+ ![Create a new Business Object](pathname:///oraclecloud/create_business_object.png)
+
+- Name: `Pres`
+- Display: `President`
+
+10. Click `Pres` Business Object and select Fields tab. Then, create a new field by clicking the `+Fields` button and select first drop-down `Field`.
+
+- Label1: `Name`
+- Type1: Click `A` (`String`)
+
+- Label2: `Index`
+- Type2: Click `#` (`Number`)
+
+![Add two new fields](pathname:///oraclecloud/creating_new_fields_name_index.png)
+
+11. Click 🖥️ Web Applications from the left sidebar and create a new Web Application by clicking `+Web Application`
+ You should have the following fields.
+
+- Application Name: `sheetjs_demo_app`
+- Navigation Style: `None`
+- Click Create
+
+12. [Adding SheetJS Module](#installation) to the App Click 📄 `Source` from the left sidebar and paste the following on `webApps/sheetjs_demo_app/app-flow.json`
+
+{`\
+"requirejs": {
+ "paths": {
+ "xlsx": "https://cdn.sheetjs.com/xlsx-${current}/package/dist/xlsx.full.min.js"
+ }
+ }
+`}
+
+
+![Adding Sheetjs to the web application](pathname:///oraclecloud/adding_sheetjs_to_app.png)
+
+
+13. Let's create the UI for our application we will be creating a table and two buttons one for import XLSX and one for export XLSX.
+
+- From the left sidebar click the 🖥️ `Web Applications` and select `main-start`
+- Select Page Designer and drag and drop two `Button` components and one `Table` Component to the canvas
+
+![Darg and drop ui components to canvas](pathname:///oraclecloud/drag_drop_components_to_canvas.png)
+
+14. Creating our button event handler
+- Now select the left button in the canvas and on the right side on `General` tab set ID to `import-xslx` and label to `Import XLSX`.
+- Now select the `Events` tab and click `+ Event Listener` drop down button and select `On 'ojAction'`
+- Now it should auto-select `Action Chains` if not click from top tab option.
+- Switch from `Design` to `Code` from top right
+
+![Switch from Design to Code in Action Chains for the button](pathname:///oraclecloud/action_chain_select_code.png)
+
+15. Replace `Action Chains > ButtonActionChain > Code` with the importing data snippet in the
+ ["Importing Data"](#importing-data-snippet) example code.
+
+16. Now repeat step 14 for the second button
+- Now select the first button in the canvas and on the right side on `General` tab set ID to `export-xslx` and label to `Export XLSX`.
+- Now select the `Events` tab and click `+ Event Listener` drop down button and select `On 'ojAction'`
+- Now it should auto-select `Action Chains` if not click from top tab option.
+- Switch from `Design` to `Code` from top right
+
+17. Replace `Action Chains > ButtonActionChain1 > Code` with the exporting data snippet in the
+ ["Exporting Data"](#exporting-data-snippet) example code.
+
+18. Connect the Business Object `Pres` to the table.
+- Now select `Page Designer` and in the canvas select the table component from the right sidebar select `Quick Start` and then `Add Data`
+- This opens up a modal on `Choose the source of your data` select `Pres` Business Object and click next.
+
+![Connecting Business Object Pres to the table](pathname:///oraclecloud/connecting_business_object.png)
+
+- On Bind Data step 2 from the left sidebar named `Endpoint Structure` check box `name` and `index1` then click next and lastly click finish.
+
+![Bind columns to field name and index1](pathname:///oraclecloud/bind_columns_to_fields_name_index1.png)
+
+19. Testing the Application
+ - a) Launch the Preview:
+ - Look for the Play (▶️) icon in the top-right corner of the Visual Builder Studio
+ - Click it to open your application in a new browser tab
+ - b) Test the Import Function:
+ - In the preview tab, click the "Import XLSX" button
+ - Navigate back to Visual Builder Studio
+ - Select the `Pres` business object
+ - Click the "Data" tab
+ - Verify that new records have been created with the president names and index
+ - Return to your application preview tab
+ - Refresh the page
+ - You should now see the table populated with the imported president data
+ - c) Test the Export Function:
+ - Click the "Export XLSX" button
+ - This will trigger an automatic download of a file named "SheetJSOracleVisualBuilderAoO.xlsx"
+ - Open the downloaded file using a spreadsheet editor.
+ - Verify that the exported data matches what was displayed in your application's table
+
+[^1]: See Oracle VBS working with [Business Objects](https://docs.oracle.com/en/cloud/paas/visual-builder/visualbuilder-building-applications/working-business-objects1.html) for more detail.
+[^2]: [Oracle Visual Builder Studio](https://docs.oracle.com/en/cloud/paas/visual-builder/)
+[^3]: Registering for a free account [on the Oracle Cloud Free Tier](https://www.oracle.com/cloud/free/) requires a valid phone number and a valid credit card.
+[^4]: See [Oracle VBS Table Component](https://docs.oracle.com/en/middleware/developer-tools/jet/13/reference-api/oj.ojTable.html) for more details.
+[^5]: See ["JavaScript Support in Oracle VBS"](https://docs.oracle.com/en/cloud/paas/visual-builder/visualbuilder-building-applications/work-javascript-editor1.html?utm_source=chatgpt.com) for more details on custom JavaScript functionality and module handling.
diff --git a/docz/static/oraclecloud/action_chain_select_code.png b/docz/static/oraclecloud/action_chain_select_code.png
new file mode 100644
index 0000000..ba42b96
Binary files /dev/null and b/docz/static/oraclecloud/action_chain_select_code.png differ
diff --git a/docz/static/oraclecloud/adding_sheetjs_to_app.png b/docz/static/oraclecloud/adding_sheetjs_to_app.png
new file mode 100644
index 0000000..667b149
Binary files /dev/null and b/docz/static/oraclecloud/adding_sheetjs_to_app.png differ
diff --git a/docz/static/oraclecloud/bind_columns_to_fields_name_index1.png b/docz/static/oraclecloud/bind_columns_to_fields_name_index1.png
new file mode 100644
index 0000000..f94affe
Binary files /dev/null and b/docz/static/oraclecloud/bind_columns_to_fields_name_index1.png differ
diff --git a/docz/static/oraclecloud/connecting_business_object.png b/docz/static/oraclecloud/connecting_business_object.png
new file mode 100644
index 0000000..49ae39e
Binary files /dev/null and b/docz/static/oraclecloud/connecting_business_object.png differ
diff --git a/docz/static/oraclecloud/create_business_object.png b/docz/static/oraclecloud/create_business_object.png
new file mode 100644
index 0000000..e0d54c6
Binary files /dev/null and b/docz/static/oraclecloud/create_business_object.png differ
diff --git a/docz/static/oraclecloud/create_vb_instance.png b/docz/static/oraclecloud/create_vb_instance.png
new file mode 100644
index 0000000..8abb4bd
Binary files /dev/null and b/docz/static/oraclecloud/create_vb_instance.png differ
diff --git a/docz/static/oraclecloud/creating_new_fields_name_index.png b/docz/static/oraclecloud/creating_new_fields_name_index.png
new file mode 100644
index 0000000..cac2a7d
Binary files /dev/null and b/docz/static/oraclecloud/creating_new_fields_name_index.png differ
diff --git a/docz/static/oraclecloud/drag_drop_components_to_canvas.png b/docz/static/oraclecloud/drag_drop_components_to_canvas.png
new file mode 100644
index 0000000..a189194
Binary files /dev/null and b/docz/static/oraclecloud/drag_drop_components_to_canvas.png differ
diff --git a/docz/static/oraclecloud/env_connect_to_instance.png b/docz/static/oraclecloud/env_connect_to_instance.png
new file mode 100644
index 0000000..0f5c5ff
Binary files /dev/null and b/docz/static/oraclecloud/env_connect_to_instance.png differ
diff --git a/docz/static/oraclecloud/launch_instance.png b/docz/static/oraclecloud/launch_instance.png
new file mode 100644
index 0000000..9b3b438
Binary files /dev/null and b/docz/static/oraclecloud/launch_instance.png differ
diff --git a/docz/static/oraclecloud/search_box_visual_builder.png b/docz/static/oraclecloud/search_box_visual_builder.png
new file mode 100644
index 0000000..8556800
Binary files /dev/null and b/docz/static/oraclecloud/search_box_visual_builder.png differ