---
title: "Quick start — Angular"
description: "Install the viewer, show a PDF, give it your color and your own button, put your own component in the toolbar, and talk to it from code."
integration: "Angular"
source: "https://www.embedpdf.com/docs/viewer/angular/quick-start"
---

# Quick start

This guide adds the viewer to your app, then makes it yours in four small steps. Each step works on
its own, so stop whenever it's enough.

## 1. Install

**`install.sh`**

```shellscript
npm install @embedpdf/viewer-angular@next
```

The package brings everything: the toolbar and panels, the PDF engine, and its WebAssembly, which
your build serves from your own site.

## 2. Show a PDF

Give the viewer a document and a height:

**`first.ts`**

```typescript
import { Component } from '@angular/core';
import { EpdfPdfViewer } from '@embedpdf/viewer-angular';

@Component({
  selector: 'app-root',
  imports: [EpdfPdfViewer],
  template: `<epdf-pdf-viewer src="/report.pdf" style="height: 100vh" />`,
})
export class App {}
```

The viewer fills the box you give it, so it needs a height: a fixed one, `100vh`, or the rest of a
flex layout. People can now scroll, zoom, search, select text, annotate, fill in forms, sign and
download.

## 3. Make it yours

The config is plain data, the same in every framework, so keep it in a file of its own. This one
uses your brand color, leaves out two features, and adds a button to the toolbar:

```js filename="viewer-config.js"
export const config = {
  theme: { accent: '#7c3aed' },
  disable: ['forms', 'redaction'],
  icons: {
    send: ['M10 14L21 3', 'M21 3l-6.5 18a.5.5 0 0 1-1 0L10 14l-7-3.5a.5.5 0 0 1 0-1L21 3z'],
  },
  commands: [
    {
      id: 'acme:send',
      label: 'Send for signature',
      icon: 'send',
      run: ({ documentId }) => fetch(`/api/send/${documentId}`, { method: 'POST' }),
    },
  ],
  layout: (layout) => layout.add('acme:send', { to: 'main', section: 'end' }),
};
```

Then give it to the viewer:

**`customized.ts`**

```typescript
import { Component } from '@angular/core';
import { EpdfPdfViewer } from '@embedpdf/viewer-angular';
import { config } from './viewer-config';

@Component({
  selector: 'app-root',
  imports: [EpdfPdfViewer],
  template: `<epdf-pdf-viewer src="/report.pdf" [config]="config" style="height: 100vh" />`,
})
export class App {
  readonly config = config;
}
```

**`customized.ts`**

```typescript
import { Component } from '@angular/core';
import { EpdfPdfViewer, type ViewerConfig } from '@embedpdf/viewer-angular';

const ebook = 'https://snippet.embedpdf.com/ebook.pdf';

@Component({
  selector: 'demo-root',
  imports: [EpdfPdfViewer],
  template: `<epdf-pdf-viewer [src]="ebook" [config]="config" style="height: 100%" />`,
})
export class App {
  readonly ebook = ebook;
  readonly config: ViewerConfig = {
    theme: { accent: '#7c3aed' },
    disable: ['forms', 'redaction'],
    icons: {
      send: ['M10 14L21 3', 'M21 3l-6.5 18a.5.5 0 0 1-1 0L10 14l-7-3.5a.5.5 0 0 1 0-1L21 3z'],
    },
    commands: [
      {
        id: 'acme:send',
        label: 'Send for signature',
        icon: 'send',
        run: () => alert('Sent for signature'),
      },
    ],
    layout: (layout) => layout.add('acme:send', { to: 'main', section: 'end' }),
  };
}
```

The new button behaves like the built-in ones: it has a tooltip, it moves into the "More" menu when
the toolbar runs out of room, and it's reachable with the keyboard. The icon is 24 × 24 SVG path
data, so [Tabler](https://tabler.io/icons) and [Lucide](https://lucide.dev) icons paste in as they
are.

## 4. Put your own component in the toolbar

A button runs one action. For anything more, such as a status from your app, put your own
component in the toolbar. Make room for it in the layout, then give the viewer the component:

**`component.ts`**

```typescript
import { Component } from '@angular/core';
import { EpdfPdfViewer, EpdfToolbarItem, type Layout } from '@embedpdf/viewer-angular';
import { DocumentStatus } from './document-status';

@Component({
  selector: 'app-root',
  imports: [EpdfPdfViewer, EpdfToolbarItem, DocumentStatus],
  template: `
    <epdf-pdf-viewer src="/report.pdf" [layout]="layout" style="height: 100vh">
      <ng-template epdfToolbarItem="status">
        <app-document-status />
      </ng-template>
    </epdf-pdf-viewer>
  `,
})
export class App {
  readonly layout = (layout: Layout) => layout.add({ custom: 'status' }, { to: 'main', section: 'end' });
}
```

Your component stays part of your app: your CSS styles it, and it reads your app's state as it
always does. The viewer only decides where it goes. See [Your own components](customize/components)
for menus, panels and the viewer's look.

## 5. Talk to the viewer

`onReady` gives you the `viewer` once it's live. This one searches each document when it opens:

**`ready.ts`**

```typescript
import { Component } from '@angular/core';
import { EpdfPdfViewer, type Viewer } from '@embedpdf/viewer-angular';

@Component({
  selector: 'app-root',
  imports: [EpdfPdfViewer],
  template: `<epdf-pdf-viewer src="/report.pdf" style="height: 100vh" (ready)="onReady($event)" />`,
})
export class App {
  onReady(viewer: Viewer) {
    viewer.documents.onOpened(() => viewer.get('search').search({ text: 'total' }));
  }
}
```

`viewer.get('search')` is the search plugin, the same one the [headless
docs](https://www.embedpdf.com/docs/headless/angular/text/search) describe. Every feature of the viewer is a plugin you can reach
this way, by its name. See [The viewer in code](code/viewer).

## Next steps

- [Setup](setup) — Sizing, server-side rendering, the engine, and several viewers on a page.
- [Layout](customize/layout) — Toolbars at the bottom, on the side, floating, or several at once.
- [Theming](customize/theming) — Your colors, light and dark, and the look of every part.
