# Unidy Web SDK — Profile

Let signed-in users view and edit their profile. Compose your own form field-by-field with <u-profile> + <u-field>, or drop in <u-full-profile> for a complete UI in one tag. Custom attributes, SSO navigation to connected services, and account deletion round it out.

## Setup

Every example below assumes the SDK is loaded and configured once per page:

```html
<script type="module" src="https://cdn.jsdelivr.net/npm/@unidy.io/sdk@1.8.1/dist/sdk/sdk.esm.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@unidy.io/sdk@1.8.1/dist/sdk/sdk.css">

<u-config
  base-url="https://hammarby.staging.unidy.app"
  api-key="your-api-key"
  locale="en"
  check-signed-in="true"></u-config>
```

## Composed profile form

u-profile loads and saves the data; each u-field renders one profile field with validation, labels and the right input type (date picker, phone, country select with flags). You own the layout — group fields in any markup you like.

- **Field-by-field composition** — u-field per profile attribute, your layout
- **Typed inputs** — dates, phone numbers, country select with icons
- **Validation + labels** — render-default-label and built-in error handling

```html
<u-signed-in>
  <!-- u-profile loads the user's data; each u-field binds one profile field.
       partial-validation limits validation to the fields rendered here. -->
  <u-profile partial-validation="true">
    <u-field field="salutation" render-default-label="true"></u-field>
    <div class="grid gap-x-4 sm:grid-cols-2">
      <u-field field="first_name" render-default-label="true"></u-field>
      <u-field field="last_name" render-default-label="true"></u-field>
      <u-field field="date_of_birth" required="true" render-default-label="true"></u-field>
      <u-field field="phone_number" render-default-label="true"></u-field>
    </div>
    <u-field field="country_code" country-code-display-option="icon" render-default-label="true"
    ></u-field>

    <u-submit-button
      class-name="mt-4 px-4 py-2 text-white bg-accent hover:bg-accent-hover rounded-lg disabled:opacity-50 w-full cursor-pointer">
      Save changes
    </u-submit-button>
  </u-profile>
</u-signed-in>

<u-signed-in not>
  <p class="text-text-light">
    Sign in on the <a href="/auth" class="text-primary underline">Auth page</a> to edit your profile.
  </p>
</u-signed-in>
```

Live demo: /profile#profile-form

## Full profile in one tag

u-full-profile renders a complete, ready-made profile editor. Use the fields attribute to pick and order fields (including custom_attributes.*), or omit it to show everything the tenant defines. The fastest path to a working account page.

- **One component** — complete profile UI with zero markup
- **Field selection** — fields="first_name,last_name,…" picks and orders

```html
<u-signed-in>
  <!-- One component, complete profile UI. Limit and order fields with the
       fields attribute — or omit it to render everything the tenant defines. -->
  <u-full-profile
    fields="first_name,last_name,date_of_birth,country_code"
    country-code-display-option="icon"></u-full-profile>
</u-signed-in>

<u-signed-in not>
  <p class="text-text-light">
    Sign in on the <a href="/auth" class="text-primary underline">Auth page</a> to see the full profile
    component.
  </p>
</u-signed-in>
```

Live demo: /profile#full-profile

## Custom attributes

Tenant-defined custom attributes behave like normal fields via u-field — or use u-raw-field to build fully custom inputs. These sport chips are plain checkboxes bound to a multi-value attribute, styled with CSS only.

- **custom_attributes.* fields** — text, select, multi-select, radio groups
- **u-raw-field escape hatch** — any UI you can build with native inputs

```html
<u-signed-in>
  <u-profile partial-validation="true">

    <!-- member_number: editable text field (profile_access: edit) -->
    <u-field field="custom_attributes.member_number" render-default-label="true"></u-field>

    <!-- active_membership: read-only radio display (profile_access: show) -->
    <u-field field="custom_attributes.active_membership" render-default-label="true"></u-field>

    <!-- favorite_nut: editable select — erdnuss / haselnuss / walnuss (profile_access: edit) -->
    <u-field field="custom_attributes.favorite_nut" render-default-label="true"></u-field>

    <u-submit-button
      class-name="mt-4 px-4 py-2 text-white bg-accent hover:bg-accent-hover rounded-lg disabled:opacity-50 w-full cursor-pointer">
      Save changes
    </u-submit-button>
  </u-profile>
</u-signed-in>

<u-signed-in not>
  <p class="text-text-light">
    Sign in on the <a href="/auth" class="text-primary underline">Auth page</a> to edit custom attributes.
  </p>
</u-signed-in>
```

Live demo: /profile#custom-attributes

## Header profile icon

The classic header pattern: u-signed-in swaps a sign-in link for an avatar menu with profile and logout entries. Pure CSS hover dropdown — no JS required.

- **Signed-in/out switch** — u-signed-in / u-signed-in not
- **u-logout-button anywhere** — style it like any menu item

```html
<!-- A header user-menu: avatar button with a hover dropdown.
     u-signed-in / u-signed-in not switch between menu and sign-in link. -->
<div class="flex justify-end">
  <u-signed-in>
    <div class="group relative inline-block">
      <button
        class="flex items-center justify-center rounded-full border border-border bg-white p-2 shadow-sm hover:bg-background-light"
        aria-label="User menu">
        <svg class="h-6 w-6" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
          <circle cx="12" cy="8" r="4"></circle>
          <path d="M4 20c0-3.5 3.5-6 8-6s8 2.5 8 6"></path>
        </svg>
      </button>

      <!-- hover bridge so the menu doesn't close between button and panel -->
      <div class="absolute left-0 right-0 top-full h-2"></div>

      <div
        class="absolute right-0 top-full z-20 mt-2 hidden w-48 rounded-lg border border-border bg-white shadow-xl group-hover:block">
        <a href="/profile" class="block px-4 py-2 text-sm hover:bg-background-light"
          >Profile settings</a
        >
        <div class="border-t border-border"></div>
        <u-logout-button
          class-name="block w-full text-left px-4 py-2 text-sm hover:bg-background-light cursor-pointer">
          Sign out
        </u-logout-button>
      </div>
    </div>
  </u-signed-in>

  <u-signed-in not>
    <a href="/auth" class="btn btn-primary !min-h-0 !px-4 !py-2 text-sm">Sign in</a>
  </u-signed-in>
</div>
```

Live demo: /profile#profile-icon

## SSO navigation & account deletion

u-jump-to-service signs the user into another OAuth app of your tenant; u-jump-to-unidy generates a one-time login token and opens Unidy's hosted pages — including the profile page where account deletion lives. no-auth skips the token for public pages.

- **Service SSO** — jump into connected apps without re-login
- **Hosted Unidy pages** — subscriptions, tickets, terms, profile
- **Account deletion** — deep-link to /profile#logindata

```html
<u-signed-in>
  <div class="flex flex-col gap-3">
    <!-- SSO into another OAuth app connected to your tenant -->
    <u-jump-to-service
      service-id="138"
      newtab
      class-name="px-4 py-2 bg-accent hover:bg-accent-hover text-white text-sm font-medium rounded-lg cursor-pointer disabled:opacity-50">
      Open connected service (SSO)
    </u-jump-to-service>

    <!-- One-time-token jump into Unidy's hosted pages -->
    <u-jump-to-unidy
      path="/subscriptions"
      newtab
      class-name="px-4 py-2 border border-border text-sm font-medium rounded-lg cursor-pointer hover:bg-background-light disabled:opacity-50">
      Manage subscriptions in Unidy
    </u-jump-to-unidy>

    <!-- Pages that need no authentication: add no-auth -->
    <u-jump-to-unidy
      path="/terms_of_use"
      no-auth
      newtab
      class-name="text-sm text-text-light underline cursor-pointer hover:text-text">
      Terms of use (no auth)
    </u-jump-to-unidy>

    <!-- Account deletion lives on Unidy's profile page — deep-link straight to it -->
    <u-jump-to-unidy
      path="/profile#logindata"
      newtab
      class-name="px-4 py-2 bg-danger hover:bg-danger-hover text-white text-sm font-medium rounded-lg cursor-pointer disabled:opacity-50">
      Delete my account
    </u-jump-to-unidy>
  </div>
</u-signed-in>

<u-signed-in not>
  <p class="text-text-light">
    Sign in on the <a href="/auth" class="text-primary underline">Auth page</a> to use SSO navigation.
  </p>
</u-signed-in>
```

Live demo: /profile#jump-and-delete

## Further reading

- Full component reference: https://github.com/UnidyID/unidy-sdk/blob/HEAD/packages/sdk/readme.md
- Official quick-start examples: https://github.com/UnidyID/unidy-sdk/blob/HEAD/packages/sdk/quick-start-examples.md
- Package: https://www.npmjs.com/package/@unidy.io/sdk
- All guides: /llms.txt
