# Using typeset.sh

### Allowing external resources&#x20;

It is important to understand that typeset.sh has strict restrictions on including external resources (such as CSS, fonts, and images) by default. A `resolveUri` function must be provided to resolve the URL of each external resource. This function receives the requested URL (e.g. `./my-logo.png`) and returns the actual path to the file, or an empty string if the resource is not found or not allowed.&#x20;

To simplify this process, you can use the `\Typesetsh\UriResolver` class to define resolvers for different schemes (e.g. "http\://", "data://", "file://").

```php
$content = "Hello <strong>World</strong>";

$base = getcwd();

$cachePath = __DIR__.'/cache';
$resolveUri = \Typesetsh\UriResolver::all($cachePath, $base);

$pdf = \Typesetsh\createPdf($content, $resolveUri);
$pdf->toFile('test.pdf');
```

{% hint style="info" %}
Note that the URI resolver receives a base path and cache path.
{% endhint %}

The *base path* is used to resolve relative URIs. For example, in the above example, `./my-logo.png` would be resolved to the path of the current working directory.

The *cache path* is used for HTTP(S) or data URIs. When an external HTTP(S) resource is used, the URI resolver will attempt to download and cache the resource to prevent the need for repeated downloads. If no cache path is provided (`null`), the URI resolver will try to use the system's default temporary file system as the cache path.

The example above uses the "`all()`" preset, which allows all paths to be included. Other presets include:

```php
// Only http(s) urls are allowed, no loca files.
\Typesetsh\UriResolver::httpOnly($cachePath);

// http(s) and the current working dir of you application.
\Typesetsh\UriResolver::httpAndCurrentDir($cachePath, $base);

// Local files only within the list of given allowed directories 
\Typesetsh\UriResolver::localOnly($allowedDirectories, $base);
```

You can create your own presets to further restrict access or even implement your own `resolveUri` method. To do this, your function must have the following signature: `function(string $uri, string $base): string`

```php
$base = __DIR__.'/public_html';
$cachePath = __DIR__.'/cache';
$allowedDirectories = [
    __DIR__.'/public_html'
];

// e.g. https://example.org/test.css
$http = new \Typesetsh\UriResolver\Http($cachePath);

// e.g. data:image/png;base64,iVBORw0KGgoAA...
$data = new \Typesetsh\UriResolver\Data($cachePath);

// e.g. file:./logo.png
$file = new \Typesetsh\UriResolver\File($allowedDirectories);

$resolveUri = new \Typesetsh\UriResolver(
    [
        'file' => $file,
        'http' => $http,
        'https' => $http,
        'data' => $data,
    ],
    $base
);

$pdf = \Typesetsh\createPdf($content, $resolveUri);
$pdf->toFile('test.pdf');
```

### Using typeset.sh

Now that you understand the concept of the $resolveUri method, let's take a quick look at how to render a PDF.&#x20;

The easiest way is to use the `\Typesetsh\createPdf` method, which returns a `\Typesetsh\Result` object. This object allows you to save the PDF to a file or retrieve it as a binary string, specify the version to save the document as, get the number of pages that were created, and retrieve a list of warnings.

```php
$pdf = \Typesetsh\createPdf("Hello World", $resolveUri);

// The version of the PDF file (default 1.6)
$pdf->version = '1.6';

// [Readonly] Number of pages that have been created.
$pdf->pageCount;

// [Readonly] List of \RuntimeException that raised durring rendering.
$pdf->issues;

// Write PDF to a file
$pdf->toFile('test.pdf');

// Return PDF as string
$data = $pdf->asString();

```

To display a PDF in the browser without saving it, you can use the `asString()` method and set the appropriate headers.

```php
$data = $pdf->asString();
header('Content-Type: application/pdf');
header('Content-Length: ' . strlen($data));
header("Content-Disposition:inline;filename=hello.pdf");

echo $data;
```

### Technical Documentation

```php
function createPdf(string $html, ?callable $resolveUri = null, int $pageLimit = 100): Result
{
    $service = new HtmlToPdf();
    return $service->render($html, $resolveUri, $pageLimit);
}

```

Create PDF function is only a simple wrapper around the HtmlToPdf service.

#### HtmlToPdf Service

A service can be configured with a **save handler** to further manipulate the final PDF (see *Save Handlers* for more details).

There are two entry points available:

1. **Single Document Rendering** – Render a single PDF from a single HTML document (standard approach).
2. **Multi-Document Rendering** – Render multiple HTML documents into a single PDF file.

#### Method Parameters

All rendering methods accept the following parameters:

* **`resolverUri` callback** – A function that takes a URI string and a base URI string, returning a local file path. This allows you to manage caching, allowlists, or other path resolution logic.\
  The class **`\Typesetsh\UriResolver`** provides several useful default implementations that can be used as-is or extended for custom behavior.
* **`pageLimit`** – Defines the maximum number of pages to process. This prevents long runtimes or excessive PDF sizes caused by malformed or corrupted HTML layouts.
  * The default value is **100 pages**.
  * If your output regularly exceeds this, consider increasing the limit.

<pre class="language-php"><code class="lang-php"><strong>/**
</strong> * Render a single html document as pdf.
 *
 * @param callable(string, string|null):string|null $resolveUri
 */
<strong>public function render(string $html, ?callable $resolveUri = null, int $pageLimit = 100): Result
</strong>
<strong>/**
</strong> * Render multiple html documents at once into a single pdf document.
 *
 * @param non-empty-list&#x3C;string> $htmls
 * @param callable(string, string|null):string|null $resolveUri
 */
public function renderMultiple(array $htmls, ?callable $resolveUri = null, int $pageLimit = 100): Result

</code></pre>

For more advanced customization, including post-processing and handling logic, refer to the [**Advanced Guide to Save Handlers**](/advanced-guides/save-handlers.md).


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.typeset.sh/setup/using-typeset.sh.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
