Library Quick Start
Follow along if you want to understand some of the key features and benefits of the Scryber.Core library. Here we add the package and build out a data template with dynamic styling and some repeating content. Based on your knowledge level you may then want to dive straight into your own use-cases to complete, or review the reference section to understand supported features.
On this page
Application Type
If you don’t have an existing application, or platform you want to add the Scryber.Core engine to, then create a new console appliction.
Scryber can be run and loaded from executables in all platforms that run dotnet, including client side Blazor WASM, but in this example we will not cover the outer execution.
Consult your own IDE documentation if you are not sure how to do this, or follow the Learning Guides articles.
Adding Scryber.Core
Whilst Scryber is open source and the code can be downloaded and built locally, the easiest way is to add the nuget package to a new or existing project. Or add the package from the command line in the project folder.
dotnet add package Scryber.Core
The package is located at https://www.nuget.org/packages/Scryber.Core
If you are focussed on MVC or Web development, then you can use the Scryber.Code.Mvc package, the adds helpers and extra support for sending PDF’s as responses to requests, and other capabilites. It also includes a reference to the matching Scryber.Core package.
dotnet add package Scryber.Core.Mvc
The package is located at https://www.nuget.org/packages/Scryber.Core.Mvc
Create a template file
The first thing we can do is add a simple html template file (the ubiquitous Hello World) as a starter and call the file ‘Hello.html’.
Hello.html
Save the file in your project, and we can move on to generate our first PDF in code.
Generate our first template
At an approprite location within your code, in the main function, or either responding to an event firing, or web request add the following
PDF Generation
//using Scryber.Components
//Load the XHTML template from a file wherever you saved it (or open stream, or text reader)
var input = "hello.html";
using var doc = Document.ParseDocument(input);
//this is your opportunity to alter ANYTHING you want in the template
//create a stream to write to - in this case a file.
using var output = new FileStream("hello.pdf", FileMode.Create);
doc.SaveAsPDF(stream); //write the pdf file.
Viewing the result
The resultant file should now be able to be opened in any PDF Viewer application or browser, and should look like this.

Troubleshooting
If it didn’t work at all, then check the package and the template structure (it needs to be valid xml and include the namespace).
If it did work, but doesn’t look like it should then you can check the logs with what SCryber is doing, using the doc.AppendTraceLog = true after parsing. Any errors that occur should appear within pages appended to the output.
Making it dynamic
This is fine, but not exactly dynamic! We can add a little more ‘pizzazz’ with some data. We can do anything we want between parsing, setting content, adding components (tables, lists, sections etc), updating styles and much more.
But - one of the core principals of scryber is a clear separation of data, to layout and style. So we can add an object to the document parameters. This can be accessed by the template during document processing.
Add our user
var input = "hello.html";
using var doc = Document.ParseDocument(input);
//set the 'user' to an instance value
doc.Params["user"] = new { firstName = "John", lastName = "Smith" };
using var output = new FileStream("hello.pdf", FileMode.Create);
doc.SaveAsPDF(stream);
Content binding syntax
The template databinding syntax is based on {{handlebars}}, which can appear in the content, or within attribute values.
<h1>Hello {{user.firstName}}</h1>
The library supports the standard ‘dot’ notation to access inner values (along with indexors ‘[]’ for arrays and dictionarys).
Personalize the template
So we can update our template to use this data within the content.
Adding expressions
With dynamic content
Generating the output we should have custom values placed naturally within the document.

Style binding syntax
Along with content, the template styles can be ‘bound’ to dynamic values using the well known var() and calc() functions.
<h1 style='color: var(brand.mainColor, black)'>Hello {{concat(user.firstName, " ", user.lastName)}}</h1>
And these can either be used directly, or indirectly through css variables, within the template styles, or referenced stylesheets.
<style>
:root{
--brand-bg : var(brand.lightColor, transparent);
}
.branded{
background-color : var(--brand-bg);
color: var(brand.mainColor);
}
</style>
Looping through content.
The library also uses the standard {{#each items}} and {{#if test}} expressions for loops and decisions.
The current item within the loop can be accessed using the this reference.
{{#if count(container.items) > 0 }}
{{#each container.items}}<span class='item'>{{this.property}}</span><{{/each}}>
{{/if }}
Extending our sample
If we add more data to our user, with some skils, and also add some custom branding.
Add our user
var input = "hello.html";
using var doc = Document.ParseDocument(input);
//set the user to an instance (or JSON) value
doc.Params["user"] = new { firstName = "John", lastName = "Smith", emailAddress = "j.smith@company.com",
skills = new[] {"C Sharp", "javascript", "scrum master", "Team leader"},
profilePicture = "" };
//add some custom style information.
doc.Params["brand"] = new { mainColor = "rgb(0,168,161)", lightColor = "silver"};
using var output = new FileStream("hello.pdf", FileMode.Create);
doc.SaveAsPDF(stream);
Update the template
We can now make some changes to our template and use the provided data to create a more useful template. Including:
- an external stylesheet for ‘font-awesome’
- adding google fonts for ‘Roboto’
- define custom css varialbles
- add a decision for a dynamic image or an icon.
- add a collection function to count items
- include a list of items if present
- add a fallback
Checking the result
Hopefully you are able re-generate and see the following output.

We have added a lot into the template - looping, images, links, styles, functions, positioning, remote fonts and stylesheets. But the static styles can be moved to a separate linked file, and the actual body is only about 20 lines long, and quite readable.
What’s next
This has been a quick dive into the capabilities of the core engine. There is still a lot that is possible!
-
Data binding functions and the reference listing
-
Dynamic SVG drawings and charts and the reference contents.
-
Typography and fonts for using the standard fonts, and including custom fonts.
-
Updating and modifying existing PDF’s using Framesets and Frames
-
Page sizes and column layout.
-
Embedding content and Attachments in files.
-
Complete CSS property support reference
-
Security, permissions and document meta-data output
-
Logging and Tracing output.
Or just jump into the Learning Guides to take you through each feature in turn.