ID
Tutorials

Complete Step-by-Step Tutorial

End-to-end tutorial covering Apps Script, GCP Console, and Nuxt Admin Portal.

A step-by-step tutorial covering how to set up Google Sheets, deploy Apps Script, configure GCP credentials, and build a full-stack Nuxt 3/4 Student Directory & Admin Management Portal.

Step 1: Create Google Sheet & Apps Script

  1. Open Google Sheets -> Create spreadsheet Student Portal -> Sheet tab students.
  2. Headers in row 1: id, name, email, grade.
  3. Open Extensions -> Apps Script -> Paste backend script:
Code.gs
function doGet(e) {
  const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(e.parameter.sheet || 'students');
  const values = sheet.getRange(e.parameter.range || 'A1:Z100').getValues();
  return ContentService.createTextOutput(JSON.stringify(values)).setMimeType(ContentService.MimeType.JSON);
}

function doPost(e) {
  const data = JSON.parse(e.postData.contents);
  const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(data.sheet || 'students');
  if (data.values) data.values.forEach(r => sheet.appendRow(r));
  return ContentService.createTextOutput(JSON.stringify({ success: true })).setMimeType(ContentService.MimeType.JSON);
}
  1. Click Deploy -> New Deployment -> Web App (Execute as: Me, Access: Anyone).
  2. Copy URL to .env:
.env
GSHEET_APPSCRIPT_URL=https://script.google.com/macros/s/.../exec
ADMIN_PASSWORD=supersecretpassword

Step 2: Build Nuxt Application Pages

Public Directory (pages/index.vue)

pages/index.vue
<script setup lang="ts">
interface Student { id: string; name: string; email: string; grade: string }
const { data: students, pending } = await useGSheetAsObject<Student[]>('A1:D50', { sheet: 'students' })
</script>

<template>
  <div>
    <h1>Student Directory</h1>
    <div v-if="pending">Loading...</div>
    <ul v-else>
      <li v-for="student in students" :key="student.id">
        {{ student.name }} ({{ student.grade }}) - {{ student.email }}
      </li>
    </ul>
  </div>
</template>

Admin Portal (pages/admin.vue)

pages/admin.vue
<script setup lang="ts">
const isAuthenticated = ref(false)
const password = ref('')
const name = ref('')
const email = ref('')

const { append } = useGSheetWrite({ sheet: 'students' })

const addStudent = async () => {
  await append('A1:D1', [[String(Date.now()).slice(-4), name.value, email.value, 'Grade 10']])
  alert('Student added to Google Sheet!')
}
</script>

<template>
  <div>
    <form v-if="!isAuthenticated" @submit.prevent="isAuthenticated = true">
      <input v-model="password" type="password" placeholder="Admin Password" required>
      <button type="submit">Login</button>
    </form>

    <form v-else @submit.prevent="addStudent">
      <input v-model="name" placeholder="Student Name" required>
      <input v-model="email" type="email" placeholder="Email" required>
      <button type="submit">Add Student</button>
    </form>
  </div>
</template>