# Nuxt

### 1. Setup JamAIBase project.

* Create a new project.

<figure><img src="/files/5M9oiKI0E3n5r3G7VQS8" alt=""><figcaption></figcaption></figure>

* Get the **Project ID**.

<div align="left"><figure><img src="/files/fCTA3D88NegoHPgQt4zk" alt=""><figcaption></figcaption></figure></div>

* Create **JamAI API Key** at **Organization > Secrets > Create API Key.**

<figure><img src="/files/00s4EbZhIkZer0XMsuoY" alt=""><figcaption></figcaption></figure>

### 2. Create a Nuxt app

```bash
npx nuxi init jamai-example-app
cd jamai-example-app
npm install
```

### 3. Install the JamAI Base client library, `jamaibase`

```bash
npm install jamaibase
```

### 4. Create a `.env` file at the root or your project and add the keys

```
PUBLIC_JAMAI_BASEURL=http://api.jamaibase.com/
JAMAI_API_KEY=your_jamai_sk_api_key
JAMAI_PROJECT_ID=your_proj_id
```

### 5. In the `nuxt.config.ts` file add runtimeConfig to use the environment variables

```javascript
runtimeConfig: {
        JAMAI_API_KEY: process.env.JAMAI_API_KEY,
        public: {
            JAMAI_BASEURL: process.env.JAMAI_BASEURL,
            JAMAI_PROJECT_ID: process.env.JAMAI_PROJECT_ID,
        },
    },
```

### 6. Create a page to list tables

We will create a page to list the tables from the project.

Create a new file `pages/index.vue` and add the following code:

```html
<template>
    <main>
        <div class="container">
            <label>Choose Table Type:</label>
            <select v-model="tableType" @change="fetchTables">
                <option value="action">Action</option>
                <option value="chat">Chat</option>
                <option value="knowledge">Knowledge</option>
            </select>
        </div>

        <div class="container">
            <h1>List of Tables</h1>
            <table>
                <thead>
                    <tr>
                        <th>Table ID</th>
                        <th>Columns</th>
                        <th>Column Type</th>
                        <th>Number of Rows</th>
                    </tr>
                </thead>
                <tbody>
                    <tr v-for="table in tableData.items" :key="table.id">
                        <td>{{ table.id }}</td>
                        <td>
                            <ul>
                                <li
                                    v-for="column in table.cols"
                                    :key="column.id"
                                >
                                    {{ column.id }}: {{ column.dtype }}
                                </li>
                            </ul>
                        </td>
                        <td>
                            <ul>
                                <li
                                    v-for="column in table.cols"
                                    :key="column.id"
                                >
                                    {{ column.gen_config ? "Output" : "Input" }}
                                </li>
                            </ul>
                        </td>
                        <td>{{ table.num_rows }}</td>
                    </tr>
                </tbody>
            </table>
        </div>
    </main>
</template>

<script setup>
import { ref, onMounted } from "vue";

const tableType = ref("action");
const tableData = ref({ items: [] });

async function fetchTables() {
    const response = await $fetch(`/api/list-tables?type=${tableType.value}`);

    if (response.success) {
        tableData.value = response.data;
    } else {
        console.error("Failed to fetch data");
    }
}

onMounted(() => {
    fetchTables();
});
</script>
```

Add the following CSS to make the UI look better:

```css
<style scoped>
/* Main layout styling */
main {
    display: flex;
    flex-direction: column;
    min-height: 100vh;
    padding: 24px;
}

/* Container styling */
.container {
    max-width: 600px;
    margin: 40px auto;
    padding: 20px;
    background-color: #fff;
    border-radius: 8px;
    box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
}

/* Label and select input styling */
label {
    display: block;
    margin-bottom: 8px;
    font-size: 14px;
    font-weight: 500;
    color: #333;
}

select {
    display: block;
    width: 100%;
    padding: 8px;
    border: 1px solid #ccc;
    border-radius: 4px;
    background-color: #fff;
    margin-bottom: 20px;
    font-size: 14px;
}

/* Table styling */
table {
    width: 100%;
    border-collapse: collapse;
    margin-top: 20px;
}

th,
td {
    padding: 12px;
    border: 1px solid #ddd;
    text-align: left;
}

th {
    background-color: #f4f4f4;
    font-weight: 600;
}

tr:nth-child(even) {
    background-color: #f9f9f9;
}

tr:hover {
    background-color: #f1f1f1;
}

/* Responsive styling */
@media (max-width: 600px) {
    .container {
        padding: 10px;
    }

    table,
    th,
    td {
        font-size: 12px;
    }

    th,
    td {
        padding: 8px;
    }
}
</style>
```

### 7. Create server handler to fetch tables:

create a new handler at `server/api/list-tables.js` and add the following code:

```javascript
import JamAI from "jamaibase";

const {
    JAMAI_API_KEY,
    public: { JAMAI_BASEURL, JAMAI_PROJECT_ID },
} = useRuntimeConfig();

const jamai = new JamAI({
    baseURL: JAMAI_BASEURL,
    apiKey: JAMAI_API_KEY,
    projectId: JAMAI_PROJECT_ID,
});

export default defineEventHandler(async (event) => {
    const { type = "action" } = getQuery(event);

    try {
        const data = await jamai.listTables({ table_type: type });
        return { success: true, data: data };
    } catch (error) {
        console.error("Error fetching tables:", error);
        return { success: false, data: "Something went wrong" };
    }
});
```

### 8. Create a page to create new action table

We will create a UI that will create a new action table.&#x20;

Create a new file `server/api/create-table.js` and add the following code:

```html
<template>
    <main>
        <h1>Create Action Table</h1>

        <div v-if="form.success">
            <p>Successfully created the table.</p>
        </div>
        <div v-else-if="form.error">
            <p>Sorry, something went wrong!</p>
        </div>

        <form @submit.prevent="submitForm">
            <label>
                Table ID
                <input v-model="tableId" />
            </label>
            <label>
                Column Name
                <input v-model="columnName" />
            </label>
            <label>
                Column Data Type
                <select v-model="columnDType">
                    <option value="str">str</option>
                    <option value="int">int</option>
                    <option value="float">float</option>
                    <option value="bool">bool</option>
                </select>
            </label>
            <button type="submit">Create</button>
        </form>
    </main>
</template>

<script setup>
import { ref } from "vue";
import { useRouter } from "vue-router";

const tableId = ref("");
const columnName = ref("");
const columnDType = ref("str");
const form = ref({ success: false, error: false });
const router = useRouter();

async function submitForm() {
    const { data } = useFetch("/api/create-table", {
        method: "post",
        headers: {
            "Content-Type": "application/json",
        },
        body: {
            table_id: tableId.value,
            column_name: columnName.value,
            column_d_type: columnDType.value,
        },
    });

    if (data.value?.success) {
        form.value.success = true;
        form.value.error = false;
    } else {
        form.value.success = false;
        form.value.error = true;
    }
}
</script>
```

### 9. Create an API to create a new table

Create a server handler at `server/api/create-table.js` to accept the request and create a new table:

```javascript
import JamAI from "jamaibase";

const {
    JAMAI_API_KEY,
    public: { JAMAI_BASEURL, JAMAI_PROJECT_ID },
} = useRuntimeConfig();

const jamai = new JamAI({
    baseURL: JAMAI_BASEURL,
    apiKey: JAMAI_API_KEY,
    projectId: JAMAI_PROJECT_ID,
});

export default defineEventHandler(async (event) => {
    const { table_id, column_name, column_d_type } = await readBody(event);

    try {
        const response = await jamai.createActionTable({
            id: table_id,
            cols: [{ id: column_name, dtype: column_d_type }],
        });

        return { success: true, data: response };
    } catch (error) {
        console.error("error: ", error.response);
        return { success: false, message: "Something went wrong!" };
    }
});
```

### 10. Add default layout

Finally, create a defalut layout (`layouts/defalut.vue`) to navigate between pages:

```html
<template>
    <div>
        <nav>
            <ul>
                <li><NuxtLink to="/">Home</NuxtLink></li>
                <li><NuxtLink to="/create-table">Create Table</NuxtLink></li>
            </ul>
        </nav>
        <slot />
    </div>
</template>

<script setup></script>

<style scoped>
nav {
    background-color: #f8f9fa;
    padding: 10px;
}

nav ul {
    list-style: none;
    padding: 0;
    margin: 0;
    display: flex;
    gap: 20px;
}

nav ul li {
    display: inline;
}

nav a {
    text-decoration: none;
    color: #007bff;
}

nav a:hover {
    text-decoration: underline;
}
</style>
```

### 12. Start the app

Start the app and go to <http://localhost:3000> in a browser and you should see the list of tables in your project.

```
npm run dev
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.jamaibase.com/developer-reference/framework-integration/nuxt.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
