Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.usehasp.com/llms.txt

Use this file to discover all available pages before exploring further.

Hasp apps receive the current user’s role from sdk.getBootstrap(). Use it to conditionally show or hide editing controls so viewers see a read-only interface while editors and admins get the full UI.

Getting the Role

Always call getBootstrap() before rendering the UI:
const bootstrap = await sdk.getBootstrap();
const { role } = bootstrap;
// role: 'viewer' | 'org_admin_viewer' | 'editor' | 'admin'

const canEdit = ['editor', 'admin'].includes(role);
const isAdmin = role === 'admin';

Hiding Controls from Viewers

async function init() {
  const bootstrap = await sdk.getBootstrap();
  const canEdit = ['editor', 'admin'].includes(bootstrap.role);

  if (canEdit) {
    document.getElementById('create-btn').style.display = 'block';
  }

  loadRecords();
}
Alternatively, use CSS classes:
if (!canEdit) {
  document.body.classList.add('readonly');
}
.readonly .edit-controls { display: none; }

Inline Edit Controls

Show edit and delete buttons only for editors/admins:
function renderRecord(record, canEdit) {
  return `
    <div class="record">
      <h3>${escapeHtml(record.title)}</h3>
      ${canEdit ? `
        <div class="actions">
          <button onclick="openEdit('${record.id}')">Edit</button>
          <button onclick="deleteRecord('${record.id}')">Delete</button>
        </div>
      ` : ''}
    </div>
  `;
}

Proactive Check Before Write

Even if the UI hides write controls for viewers, always handle AccessDenied errors gracefully in case the role changes mid-session:
const { ErrorCode, HaspSDKError } = HaspSDK;

try {
  await sdk.createRecord('tasks', data);
} catch (error) {
  if (error instanceof HaspSDKError && error.code === ErrorCode.AccessDenied) {
    showMessage('You do not have permission to create records.');
  }
}

Bootstrap Data

getBootstrap() returns more than just the role:
const bootstrap = await sdk.getBootstrap();
// bootstrap.user   — { id, name, email }
// bootstrap.role   — 'viewer' | 'org_admin_viewer' | 'editor' | 'admin'
// bootstrap.app    — { id, name, type }
// bootstrap.limits — { maxPageSize, maxRecordCount, rateLimitPerMinute }
You can use bootstrap.user to personalize the UI or pre-fill the current user’s email in a form.