# OpenQTR Script SDK — Expert Guide

Embed the SDK via a `<script>` tag and generate QR codes directly in the browser — no bundler, no framework, no React required.

---

## Quick Start

```html
<script src="https://cdn.jsdelivr.net/npm/@satirr/openqtr/dist/sdk.js"></script>
<div id="qr"></div>
<script>
  OpenQTR.generate({
    text: "https://example.com",
    element: "#qr",
    size: 250,
  });
</script>
```

---

## Installation

### Option 1: CDN (recommended)

```html
<script src="https://cdn.jsdelivr.net/npm/@satirr/openqtr/dist/sdk.js"></script>
```

Minified IIFE — everything bundled into a single file. No additional dependencies required.

### Option 2: Self-host (fallback)

If you're running the OpenQTR app on your own server, the SDK is also served at `/openqtr-sdk.js`:

```html
<script src="/openqtr-sdk.js"></script>
```

Otherwise, download the SDK file and place it in your project's `public/` or `assets/` directory, then add a `<script>` tag pointing to the local path.

### Option 3: Build from source

```bash
git clone https://gitlab.com/satirr/openqtr.git
cd openqtr
npm install
npm run build:sdk
# Output: dist/sdk.js
```

---

## API Reference

### `OpenQTR.generate(options)`

Renders a QR code into the specified DOM element.

#### Options

| Property | Type | Default | Required | Description |
|---|---|---|---|---|
| `text` | `string` | — | **Yes** | The data to encode in the QR code. Must be a non-empty string. |
| `element` | `string` \| `HTMLElement` | — | **Yes** | CSS selector (e.g. `"#qr"`, `".qr-container"`) or a direct `HTMLElement` reference. |
| `size` | `number` | `200` | No | Width and height of the QR code in pixels. |
| `format` | `"png"` \| `"svg"` | `"png"` | No | Output format. `"png"` renders a raster image; `"svg"` renders a scalable vector. |
| `fgColor` | `string` | `"#000000"` | No | Foreground color (the dark modules). Any valid CSS color string. |
| `bgColor` | `string` | `"#ffffff"` | No | Background color (the light/empty space). Any valid CSS color string. |
| `errorCorrectionLevel` | `"L"` \| `"M"` \| `"Q"` \| `"H"` | `"M"` | No | Error correction level. Higher levels tolerate more damage but produce denser codes. |

#### Error correction levels

| Level | Recovery capacity | Typical use |
|---|---|---|
| `L` | ~7% | High density, low damage risk |
| `M` | ~15% | Balanced (default) |
| `Q` | ~25% | Moderate damage risk |
| `H` | ~30% | Maximum resilience, smaller data capacity |

---

## Examples

### Basic PNG QR code

```html
<div id="qr"></div>
<script>
  OpenQTR.generate({
    text: "https://example.com",
    element: "#qr",
  });
</script>
```

### Large SVG QR code with custom colors

```html
<div id="qr" style="background:#1a1a2e; padding:20px; display:inline-block;"></div>
<script>
  OpenQTR.generate({
    text: "Hello World",
    element: "#qr",
    size: 400,
    format: "svg",
    fgColor: "#e94560",
    bgColor: "transparent",
    errorCorrectionLevel: "H",
  });
</script>
```

### Using an HTMLElement reference

```html
<div id="container"></div>
<script>
  const el = document.getElementById("container");
  OpenQTR.generate({
    text: "WiFi Network",
    element: el,
    size: 150,
  });
</script>
```

---

## Error Handling

`OpenQTR.generate()` throws an `OpenQTRError` in the following cases:

| Error code | Condition |
|---|---|
| `EMPTY_TEXT` | `text` is missing, empty, or not a string |
| `INVALID_ELEMENT` | `element` is neither a string nor an `HTMLElement` |
| `ELEMENT_NOT_FOUND` | CSS selector matches no element in the DOM |
| `INVALID_FORMAT` | `format` is not `"png"` or `"svg"` |

**Recommended usage with error handling:**

```javascript
try {
  OpenQTR.generate({ text: "", element: "#qr" });
} catch (err) {
  if (err.name === "OpenQTRError") {
    console.error(`OpenQTR error [${err.code}]: ${err.message}`);
    // Show user-friendly feedback
  } else {
    console.error("Unexpected error:", err);
  }
}
```

---

## Rendering Internals

### PNG pipeline

1. `qrcode.create()` generates the module matrix from the input text.
2. An in-memory `<canvas>` element is created at 2x resolution (HiDPI).
3. Modules are drawn as `fillRect` calls on the canvas context.
4. `canvas.toDataURL("image/png")` produces a base64 PNG data URL.
5. An `<img>` element is appended to the target container.

### SVG pipeline

1. `qrcode.create()` generates the module matrix.
2. An SVG string is built programmatically with `<rect>` elements for each module.
3. The SVG string is injected as `innerHTML` of the target container.

---

## Browser Support

Works in all modern browsers (Chrome, Firefox, Safari, Edge, Opera). Requires Canvas API support for PNG output.

---

## Limitations

- **No logo overlay** — The SDK intentionally stays minimal. For logos/gradients/custom dot shapes, use the [full OpenQTR web app](https://gitlab.com/satirr/openqtr).
- **No React/Vue/Angular bindings** — Use the vanilla JS API inside `useEffect` / `onMounted` / `ngAfterViewInit` as needed.
- **Single QR per call** — Each call to `generate()` replaces the contents of the target element. Call `generate()` multiple times for multiple QR codes.

---

## Development

```bash
# Build the SDK
npm run build:sdk

# Watch mode
npx tsup --watch
```
