Step by step on How to Export PDF in Angular

Step by step on How to Export PDF in Angular

If you need to save as a PDF or want to take a print-out of any other HTML elements like Table, Div or any Grid in Angular, you can do that easily. Follow the steps for an example of how to do a  PDF Export

Exporting an HTML element is like a snapshot for sharing some information in the form of documents, and it may be used for reporting too. So, if you need to save as a PDF or want to take a print-out of any other HTML elements like Table, Div or any Grid in Angular, you can do that easily.

Follow the steps for an example of how to do a  PDF Export.

Step 1

Create an Angular application using CLI or any other method you want.

Step 2

Open this application code in any editor like Visual Studio Code.

Step 3

For demo grid data, declare a variable with some sample data.

Data = [  
    { Id: 101, Name: 'Nitin', Salary: 1234 },  
    { Id: 102, Name: 'Sonu', Salary: 1234 },  
    { Id: 103, Name: 'Mohit', Salary: 1234 },  
    { Id: 104, Name: 'Rahul', Salary: 1234 },  
    { Id: 105, Name: 'Kunal', Salary: 1234 }  
  ];  

Step 4

Bind that data with an HTML table or any element, this must how you want your PDF Document. In my app.component.html, I just replaced the default HTML with the following HTML code. In this code, I bind that data variable from my component to this table.

<h1>This is an Angular App!</h1>    
<div>    
    <table>    
        <tr>    
            <th>Id</th>    
            <th>Name</th>    
            <th>Salary</th>    
        </tr>    
        <tr *ngFor="let item of Data">    
            <th>{{item.Id}}</th>    
            <th>{{item.Name}}</th>    
            <th>{{item.Salary}}</th>    
        </tr>    
    </table>    
</div>     

Now serve your Angular App in the browser using “ng serve --o”, this will be the default output.

I know this is not the output that you want to download, so use the formatting and modify this as you need. In my Demo App, I’ll use bootstrap just for a simple table format.

Step 5

Add Bootstrap using CLI in your project and apply the “table table-dark” class on that HTML table. Use the following CLI command to add bootstrap in your project,

“npm install bootstrap –save”

Step 6

After adding bootstrap in your application, apply the required bootstrap classes like this,

<div class="container">  
    <table class="table table-dark">  
        <tr>  
            <th>Id</th>  
            <th>Name</th>  
            <th>Salary</th>  
        </tr>  
        <tr *ngFor="let item of Data">  
            <th>{{item.Id}}</th>  
            <th>{{item.Name}}</th>  
            <th>{{item.Salary}}</th>  
        </tr>  
    </table>  

And now output must be like this,

Step 7

Add a button to download this table as a pdf.

<input type="button" value="Download PDF" class="btn btn-success" (click)="SavePDF()">  

Also, add a click event handler for this button in your app.component.ts like,

public SavePDF():void{  
  
  }  

Step 8

Now Add jspdf and @types/jspdf in your application using the following command,

_“_npm install jspdf --save”

and

_“_npm install @types/jspdf --save-dev”

Step 9

Give a ref name and id to that HTML element you need to export as PDF and get the ref of that HTML element in your component using @ViewChild, like,

<div class="container" id="content" #content>  
  
 @ViewChild('content') content:ElementRef;  

Step 10

Now at this last step, you have to write the following code in your button click handler function, where we create a jspdf variable as doc and configured it with some required permeates like Doc width, margin, and content,

import * as jsPDF from 'jspdf';  
public SavePDF(): void {  
    let content=this.content.nativeElement;  
    let doc = new jsPDF();  
    let _elementHandlers =  
    {  
      '#editor':function(element,renderer){  
        return true;  
      }  
    };  
    doc.fromHTML(content.innerHTML,15,15,{  
  
      'width':190,  
      'elementHandlers':_elementHandlers  
    });  
  
    doc.save('test.pdf');  
  }  

Now serve your application “ng serve --o” and your output must be like this,

Click on the Download PDF button and get the file.

Full Code

App.component.html

<div class="container">  
    <h1>This is an Angular App!</h1>  
    <input type="button" value="Download PDF" class="btn btn-success" (click)="SavePDF()">  
    <br/><br/>  
    <div class="container" id="content" #content>  
        <table class="table table-dark">  
            <tr>  
                <th>Id</th>  
                <th>Name</th>  
                <th>Salary</th>  
            </tr>  
            <tr *ngFor="let item of Data">  
                <th>{{item.Id}}</th>  
                <th>{{item.Name}}</th>  
                <th>{{item.Salary}}</th>  
            </tr>  
        </table>  
    </div>  
</div>  

App.component.ts

import { Component, ViewChild, ElementRef } from '@angular/core';  
import * as jsPDF from 'jspdf';  
  
@Component({  
  selector: 'app-root',  
  templateUrl: './app.component.html',  
  styleUrls: ['./app.component.css']  
})  
  
export class AppComponent {  
  title = 'app';  
  Data = [  
    { Id: 101, Name: 'Nitin', Salary: 1234 },  
    { Id: 102, Name: 'Sonu', Salary: 1234 },  
    { Id: 103, Name: 'Mohit', Salary: 1234 },  
    { Id: 104, Name: 'Rahul', Salary: 1234 },  
    { Id: 105, Name: 'Kunal', Salary: 1234 }  
  ];  
  
  @ViewChild('content') content: ElementRef;  
  public SavePDF(): void {  
    let content=this.content.nativeElement;  
    let doc = new jsPDF();  
    let _elementHandlers =  
    {  
      '#editor':function(element,renderer){  
        return true;  
      }  
    };  
    doc.fromHTML(content.innerHTML,15,15,{  
  
      'width':190,  
      'elementHandlers':_elementHandlers  
    });  
  
    doc.save('test.pdf');  
  }  
}  

I hope it’ll work for you, keep sharing, thank you!

How To Convert HTML To PDF using JavaScript

How To Convert HTML To PDF using JavaScript

In this tutorial, we will show you how to generate PDF file of your HTML page with CSS using JavaScript and jQuery. We have to add two external JS files for converting the PDF -  JSPDF.js and html2canvas.js.

In this blog, I will demonstrate how to generate PDF file of your HTML page with CSS using JavaScript and jQuery. We have to add two external JS files for converting the PDF -  JSPDF.js and html2canvas.js.

Creating an HTML Page for converting the HTMl to PDF

Add the following table in your HTML page.

<form class="form" style="max-width: none; width: 1005px;">  
  
  
        <h2 style="color: #0094ff">Hello</h2>  
        <h3>a bit about this Project:</h3>  
        <p style="font-size: large">  
            I will demonstrate how to generate PDF file of your HTML page with CSS using JavaScript and J query.  
        </p>  
        <table>  
            <tbody>  
                <tr>  
                    <th>Company</th>  
                    <th>Contact</th>  
                    <th>Country</th>  
                </tr>  
                <tr>  
                    <td>Alfreds Futterkiste</td>  
                    <td>Maria Anders</td>  
                    <td>Germany</td>  
                </tr>  
                <tr>  
                    <td>Centro comercial Moctezuma</td>  
                    <td>Francisco Chang</td>  
                    <td>Mexico</td>  
                </tr>  
                <tr>  
                    <td>Ernst Handel</td>  
                    <td>Roland Mendel</td>  
                    <td>Austria</td>  
                </tr>  
                <tr>  
                    <td>Island Trading</td>  
                    <td>Helen Bennett</td>  
                    <td>UK</td>  
                </tr>  
                <tr>  
                    <td>Laughing Bacchus Winecellars</td>  
                    <td>Yoshi Tannamuri</td>  
                    <td>Canada</td>  
                </tr>  
                <tr>  
                    <td>Magazzini Alimentari Riuniti</td>  
                    <td>Giovanni Rovelli</td>  
                    <td>Italy</td>  
                </tr>  
            </tbody>  
        </table>  
  
  
    </form>  

Add the style of this HTML page.

<style>  
        table {  
            font-family: arial, sans-serif;  
            border-collapse: collapse;  
            width: 100%;  
        }  
  
        td, th {  
            border: 1px solid #dddddd;  
            text-align: left;  
            padding: 8px;  
        }  
  
        tr:nth-child(even) {  
            background-color: #dddddd;  
        }  
    </style>  

Add the "Print" button in this page, above the form tag.

<input type="button" id="create_pdf" value="Generate PDF">  

Add the following script in HTML page for converting it to pdf.

<script src="https://code.jquery.com/jquery-1.12.4.min.js" integrity="sha256-ZosEbRLbNQzLpnKIkEdrPv7lOy9C27hHQ+Xp8a4MxAQ=" crossorigin="anonymous"></script>  
   <script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/1.3.5/jspdf.min.js"></script>  

Add other two scripts for converting the document.

<script>  
    (function () {  
        var  
         form = $('.form'),  
         cache_width = form.width(),  
         a4 = [595.28, 841.89]; // for a4 size paper width and height  
  
        $('#create_pdf').on('click', function () {  
            $('body').scrollTop(0);  
            createPDF();  
        });  
        //create pdf  
        function createPDF() {  
            getCanvas().then(function (canvas) {  
                var  
                 img = canvas.toDataURL("image/png"),  
                 doc = new jsPDF({  
                     unit: 'px',  
                     format: 'a4'  
                 });  
                doc.addImage(img, 'JPEG', 20, 20);  
                doc.save('Bhavdip-html-to-pdf.pdf');  
                form.width(cache_width);  
            });  
        }  
  
        // create canvas object  
        function getCanvas() {  
            form.width((a4[0] * 1.33333) - 80).css('max-width', 'none');  
            return html2canvas(form, {  
                imageTimeout: 2000,  
                removeContainer: true  
            });  
        }  
  
    }());  
</script>  
<script>  
    /* 
 * jQuery helper plugin for examples and tests 
 */  
    (function ($) {  
        $.fn.html2canvas = function (options) {  
            var date = new Date(),  
            $message = null,  
            timeoutTimer = false,  
            timer = date.getTime();  
            html2canvas.logging = options && options.logging;  
            html2canvas.Preload(this[0], $.extend({  
                complete: function (images) {  
                    var queue = html2canvas.Parse(this[0], images, options),  
                    $canvas = $(html2canvas.Renderer(queue, options)),  
                    finishTime = new Date();  
  
                    $canvas.css({ position: 'absolute', left: 0, top: 0 }).appendTo(document.body);  
                    $canvas.siblings().toggle();  
  
                    $(window).click(function () {  
                        if (!$canvas.is(':visible')) {  
                            $canvas.toggle().siblings().toggle();  
                            throwMessage("Canvas Render visible");  
                        } else {  
                            $canvas.siblings().toggle();  
                            $canvas.toggle();  
                            throwMessage("Canvas Render hidden");  
                        }  
                    });  
                    throwMessage('Screenshot created in ' + ((finishTime.getTime() - timer) / 1000) + " seconds<br />", 4000);  
                }  
            }, options));  
  
            function throwMessage(msg, duration) {  
                window.clearTimeout(timeoutTimer);  
                timeoutTimer = window.setTimeout(function () {  
                    $message.fadeOut(function () {  
                        $message.remove();  
                    });  
                }, duration || 2000);  
                if ($message)  
                    $message.remove();  
                $message = $('<div ></div>').html(msg).css({  
                    margin: 0,  
                    padding: 10,  
                    background: "#000",  
                    opacity: 0.7,  
                    position: "fixed",  
                    top: 10,  
                    right: 10,  
                    fontFamily: 'Tahoma',  
                    color: '#fff',  
                    fontSize: 12,  
                    borderRadius: 12,  
                    width: 'auto',  
                    height: 'auto',  
                    textAlign: 'center',  
                    textDecoration: 'none'  
                }).hide().fadeIn().appendTo('body');  
            }  
        };  
    })(jQuery);  
  
</script>  

Now, let's see the output.

Click on the "Generate PDF " button and get the PDF file like this.

Conclusion

You can easily add the Export to PDF functionality in the web page without depending on the server-side script. The PDF creation functionality can be enhanced with jsPDF configuration options as per your needs. Thank you for reading !

How to export Angular page content to PDF with Kendo UI

How to export Angular page content to PDF with Kendo UI

In this tutorial, learn how to easily export pages with HTML content within your Angular application. This should be a complex task, but thanks to a Kendo UI component it is easy

If you've found yourself looking for an easy solution to smoothly export the HTML content from your Angular application to a PDF, then this is the appropriate post for you. We may need to export HTML content to PDF for several reasons, ranging from sharing it with others without necessarily accessing the internet to saving it just for documentation purposes.

Building a solution for a component like this could be time-consuming if you are building all by yourself. In this post, I will show you how to easily achieve this by leveraging the PDF export component provided by Kendo UI.

We will build an Angular application with some dummy content and add a Kendo UI button to export the content directly to PDF as shown here:

Install Angular CLI

Before creating an Angular application, you need to first install the Angular CLI if it doesn’t already exist on your machine. Open up a terminal and run the following command for that purpose:

npm install -g @angular/cli 

This will add the Angular CLI globally on your machine.

Creating Angular Application

You can now proceed to create a new app for the purpose of this post by running the command below to generate an application with the name kendo-angular-export-pdf:

ng new kendo-angular-export-pdf

Once the installation process is complete, change directory into the newly created project as shown below and start the application:

// change directory
cd kendo-angular-export-pdf
   
// start the application
ng serve

You may experience an error with the message below in your console:

ERROR in node_modules/rxjs/internal/types.d.ts(81,44): error TS1005: ';' expected.
node_modules/rxjs/internal/types.d.ts(81,74): error TS1005: ';' expected.
node_modules/rxjs/internal/types.d.ts(81,77): error TS1109: Expression expected.

This is a known issue on GitHub and it’s due to lack of compatibility between the current version of TypeScript on your machine and rxjs. The quick way to fix this is to delete the node_modules folder. Now, open the package.json file and within the dependencies object, edit the rxjs by removing ^ :

 "dependencies": {
   ...
   "rxjs": "6.0.0", // remove the `^`
   "zone.js": "^0.8.26"
 },

Save the file and run the npm install command again. Once the installation process is complete, you can now proceed to start the application with ng serve.

This will compile your application and start the development server. To view the default page of this Angular application, navigate to http://localhost:4200 from your favorite browser and you will see this:

Add PDF Export Component from Kendo UI

Next, we’ll need to add the PDF export component before we start using it in our application. To achieve that, we’ll use the ng add command to require and install the package as shown here:

ng add @progress/kendo-angular-pdf-export

This will import and add both PDFExportModule and BrowserAnimationsModule to the app.module.ts file:

// ./src/app/app/module.ts
   
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppComponent } from './app.component';
import { PDFExportModule } from '@progress/kendo-angular-pdf-export';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
   
   
@NgModule({
 declarations: [
   AppComponent
 ],
 imports: [
   BrowserModule,
   PDFExportModule,
   BrowserAnimationsModule
 ],
 providers: [],
 bootstrap: [AppComponent]
})
export class AppModule { }
Use the Kendo PDF Export Component

After installing the PDF export package, you can now proceed to export content within our Angular application to PDF by placing it within the <kendo-pdf-export> component. Open ./src/app/app.component.html and replace its content with:

// ./src/app/app.component.html
   
<div class="pageWrapper">
 <div class="content">
   <kendo-pdf-export #pdf>
     <div class="size-a4">
       <p> Build Better JavaScript Apps Faster The ultimate collection of JavaScript UI components with libraries for jQuery,
         Angular, React, and Vue. Quickly build eye-catching and high-performance responsive web applications—regardless
         of your JavaScript framework choice.
       </p>
       <p> Build Better JavaScript Apps Faster The ultimate collection of JavaScript UI components with libraries for jQuery,
         Angular, React, and Vue. Quickly build eye-catching and high-performance responsive web applications—regardless
         of your JavaScript framework choice.
       </p>
     </div>
   </kendo-pdf-export>
   
   <div>
     <button kendo-button (click)="pdf.saveAs('demo-content.pdf')">
       Export As PDF
     </button>
   </div>
 </div>
</div>

Here, we have added dummy content and wrapped it with the <kendo-pdf-export></kendo-pdf-export> component. Next we added a button and attached a click event to it. Once the button is clicked, we called the saveAs() method in order to save the generated file. The file will be saved as the name passed as an argument to the saveAs() method.

Finally, to give the page some default styling, add the following content to ./src/app/app.component.css file:

// ./src/app/app.component.css
   
.pageWrapper {
 margin-top: 50px;
}
button {
   padding: 15px;
}
kendo-pdf-export {
 font-family: "DejaVu Sans", "Arial", sans-serif;
 font-size: 16px;
}
.content {
 width: 800px;
 margin: 0 auto;
 line-height: 20px;
}

Now proceed to start the application again by running ng serve from the terminal within the application’s directory. Once

the application is built and served on http://localhost:4200 you will see this:

The content displayed here is from our Angular application. To test the HTML content export functionality, click on the Kendo button with the text Export As PDF. Now open the downloaded PDF file:

Cool, right? This is the content of our page exported to PDF without much hassle. But with a close look at the PDF file, you will agree with me that something isn’t right. The content doesn’t look properly organized. We’ll change that by adding a little bit of margin in the next section.

Add Paper Size and Margin

The Kendo PDF export component API makes a provision for us to easily customize and specify the paper size of the PDF document. At the moment, it is set to the default auto which means that the paper size is determined by the content.

Let’s replace the content of ./src/app/app.component.html with:

// ./src/app/app.component.html
   
<div class="pageWrapper">
 <div class="content">
   <kendo-pdf-export #pdf paperSize="A4" margin="2cm">
     <div class="size-a4">
       <p> Build Better JavaScript Apps Faster The ultimate collection of JavaScript UI components with libraries for jQuery,
         Angular, React, and Vue. Quickly build eye-catching and high-performance responsive web applications—regardless
         of your JavaScript framework choice.
       </p>
       <p> Build Better JavaScript Apps Faster The ultimate collection of JavaScript UI components with libraries for jQuery,
         Angular, React, and Vue. Quickly build eye-catching and high-performance responsive web applications—regardless
         of your JavaScript framework choice.
       </p>
     </div>
   </kendo-pdf-export>
   
   <div>
     <button kendo-button (click)="pdf.saveAs('demo-content.pdf')">
       Export As PDF
     </button>
   </div>
 </div>
</div>

We have added two data attributes to the <kendo-pdf-export>, which are:

  • paperSize: We set this to A4.
  • margin: We set this to 2cm.

Check the page again and click on the Export As PDF button. Now proceed to open your downloaded PDF file and you will notice that it looks much better as shown below:

Conclusion

The Kendo PDF export component as shown here is a solution for exporting and handling HTML content to PDF. This comes in handy whenever you need to quickly save a page as a PDF document from your Angular application.

We have barely scratched the surface here, because there is so much more functionality provided by the Kendo UI team when exporting HTML content to PDF. Feel free to explore the API by checking the link here for more details.

Hopefully you have learned a lot from this post. Check the source code here on GitHub.

Thanks for reading

If you liked this post, share it with all of your programming buddies!

Follow us on Facebook | Twitter

Further reading about Angular

Angular 8 (formerly Angular 2) - The Complete Guide

Angular & NodeJS - The MEAN Stack Guide

The Complete Node.js Developer Course (3rd Edition)

The Web Developer Bootcamp

Best 50 Angular Interview Questions for Frontend Developers in 2019

How to build a CRUD Web App with Angular 8.0

React vs Angular: An In-depth Comparison

React vs Angular vs Vue.js by Example

Microfrontends — Connecting JavaScript frameworks together (React, Angular, Vue etc)

Building CRUD Mobile App using Ionic 4, Angular 8

How to Build Mobile Apps with Angular, Ionic 4, and Spring Boot

Ionic 4 & Angular Tutorial For Beginners - Crash Course

Render HTML with Vanilla JavaScript and lit-html

Render HTML with Vanilla JavaScript and lit-html

Sometimes you need to render HTML elements on a web page. And like Goldilocks' search for "just right", you have to try a few techniques before you find the right one. Using a framework may be too hard. Using pure HTML and the DOM API may be too soft. What you need is something in the middle that is just right. Is lit-html "just right"? Let's find out.

Sometimes you need to render HTML elements on a web page. And like Goldilocks' search for "just right", you have to try a few techniques before you find the right one. Using a framework may be too hard. Using pure HTML and the DOM API may be too soft. What you need is something in the middle that is just right. Is lit-html "just right"? Let's find out.

First, I'll show how this all works. Then at the end of this article, I'll explain everything you need to get started with lit-html to try this for yourself.

When you're done, you can push your HTML app with lit-html to the cloud to see it in all of its glory! I included a link to a free Azure trial, so you can try it yourself.

Resources:

The Sample App

Here is the app I'll demonstrate in this article. It fetches a list of heroes and renders them when you click the button. It also renders a progress indicator while it is fetching.

What's the Value of lit-html

When you focus on rendering content, and nothing else, lit-html is a good fit. It works closely with the DOM to render content, and refresh it in an optimal manner. The docs can provide you with more details, but the basic code for lit-html looks like this.

// Credit: As seen in official docs https://lit-html.polymer-project.org/guide/getting-started

// Import lit-html
import { html, render } from 'lit-html';

// Define a template
const myTemplate = name =>
  html`
    <p>Hello ${name}</p>
  `;

// Render the template to the document
render(myTemplate('World'), document.body);

You import lit-html, define a template, then render it to the DOM. That's it!

Rendering HTML

A progress bar is fairly basic. There is some HTML, and we show it when needed and hide it when it is not required. While we could use a template, or innerHTML, or the DOM API for this, let's see what this would look like with lit-html.

First, we get a reference to the element in the DOM where the progress bar will appear.

Then we define the template. This code looks and feels like JSX (or TSX). The advantage here is that you can write the HTML. You wrap the HTML in a template string (notice the back-tick character is used and not a single quote). Template strings allow you to span lines and insert variables where needed (we'll see this soon). The magic that makes this work is the html tag that precedes the template string. The html tag is what tells lit-html that you are about to define a template.

Next, we compile the template and pass those results to lit-html's render function, which places the results in the DOM. Finally, we hide or show the progress bar as needed.

function showProgress(show = true) {
  const container = document.getElementById('progress-placeholder');

  const template: () => TemplateResult = () => html`
    <progress class="progress is-medium is-info" max="100"></progress>
  `;
  const result = template();
  render(result, container);

  container.style.display = show ? 'block' : 'none';
}

Now you can run this showProgress function any time you want to show the progress bar.

Note that when a template is re-rendered, the only part that is updated is the data that changed. If no data changed, nothing is updated.

Rendering HTML with Dynamic Values

The progress bar does not change each time it is rendered. You will have situations where you want your HTML to change. For example, you may have a message area on your web app that shows a styled message box with a title and a message. The title and message will change every time you show the message area. Now you have dynamic values.

The HTML is defined with a template string, so it is trivial to add a variable into it. Notice the code below adds a title and text into the template, using the ${data.title} and ${data.text} syntax, respectively.

Then the template is compiled and rendered were needed.

When this template is re-rendered, the only part that is updated is the data that changed. In this case, that's the title and text.

function showMessage(text: string, title = 'Info') {
  const template: (data: any) => TemplateResult = (data: Message) => html`
    <div id="message-box" class="message is-info">
      <h3 class="message-header">${data.title}</h3>
      <p class="message-body">${data.text}</p>
    </div>
  `;

  const el = document.getElementById('message-placeholder');
  const result = template({ title, text });
  render(result, el);

  el.style.visibility = !!text ? 'visible' : 'hidden';
}

Rendering a List

Things get a little more real when we render a list. Let's think about that for a moment. A list requires that we have a plan if there is data and a backup plan if there is no data. A list requires that we render the same thing for each row, and we don't know how many rows we have. A list requires that we pass different values for each row, too. Then we have to take the rows and wrap them in a container such as a <ul> or a <table>.

So there is a little more logic here, regardless of whether we use lit-html or any other technique. Let's explore how the replaceHeroList function renders the rows using lit-html.

function replaceHeroList(heroes?: Hero[]) {
 const heroPlaceholder = document.querySelector('.hero-list');

 // Define the template
 let template: () => TemplateResult;

 if (heroes && heroes.length) {
   // Create the template for every hero row
   template = createList();
 } else {
   // Create the template with a simple "not found" message
   template = () =>
     html`
       <p>heroes not found</p>
     `;
 }

 // Compile the template
 const result = template();

 // Render the template
 render(result, heroPlaceholder);

Notice that when there are heroes, we call the createList function. This function begins by creating an array of TemplateResult. So for every hero in the heroes array, we define a template that represents the <li> containing the HTML that displays that respective hero.

Then we create another template that contains the <ul> and embeds the array of hero templates. It's pretty cool that we can embed templates like this! Finally, we return it all and let the logic compile the templates and render them.

function createList() {
  // Create an array of the templates for each hero
  const templates: TemplateResult[] = heroes.map(hero => {
    return html`
      <li>
        <div class="card">
          <div class="card-content">
            <div class="content">
              <div class="name">${hero.name}</div>
              <div class="description">${hero.description}</div>
            </div>
          </div>
        </div>
      </li>
    `;
  });

  // Create a template that includes the hero templates
  const ulTemplate: () => TemplateResult = () =>
    html`
      <ul>
        ${templates}
      </ul>
    `;
  return ulTemplate;
}

Summary

When you want to render HTML, lit-html is a fast and light-weight option. Is it better than using templates and the DOM API? You'll have to decide what is best for you. But the real story here is that you have another great option to consider when determining the right tool for your job.

Prologue

You can also get editor help with your lit-html templates. Notice the image below shows the syntax highlighting for the HTML template!

Setup

You can install the lit-html package with npm.

npm install lit-html

Alternately you can load it directly from the unpkg.com CDN

import { html, render } from 'https://unpkg.com/lit-html?module';

You have a choice here. npm is my preference, but feel 100% free to use the CDN if that suits you.

TypeScript and lit-html

You only need to include the library for lit-html and you're done. But I like to use TypeScript, and I absolutely recommend enabling your tooling to work great with typeScript and lit-html.

Let me be very clear here - you do not need TypeScript. I choose to use it because it helps identify mistakes while I write code. If you don't want TypeScript, you can opt to use plain JavaScript.

Here are the steps to make TypeScript and lit-html light up together:

  1. Install TypeScript support for lit-html
  2. Configure your tsconfig.json file
  3. Install the VS Code extension for lit-html

Run this command to install the plugin and typescript, as development dependencies to your project.

npm install --save-dev typescript-lit-html-plugin typescript

Edit your tsconfig.json by adding the following to your compilerOptions section.

"compilerOptions": {
  "plugins": [
    {
      "name": "typescript-lit-html-plugin"
    }
  ]
}

Finally, install the VS Code extension for lit-html.

Now you get syntax highlighting for all of your lit-html templates!