Generate a PDF Certificate from an eLearning Course

Generate a PDF certificate from eLearning tutorial cover photo

Do you want to add a PDF certificate that people can download upon completing an eLearning course or passing an important exam? Well, with a bit of JavaScript, you can!

In this tutorial, you’ll learn how to generate a PDF certificate that includes the user’s name and date from any eLearning course.  Here is a working demo. Also, at the time of writing, this solution will not work with Internet Explorer.

We will use Articulate Storyline 360 for the purposes of this tutorial, but if you know how to capture user info, execute JavaScript, and modify the published output folder with your tool of choice, then you will be able to use the same steps that we use here.

Also, while we will focus on a completion certificate in this tutorial, you can use what you learn here to create dynamic PDF job aids, study guides, and more.

Let’s get started!

Design the PDF Certificate

First, we need to design the certificate that we’re going to present to the user. 

We’ll leave placeholders for the information that will be entered by the user, such as their name, but we can design everything else in a tool like Adobe Illustrator or Indesign. If you have a graphic design or print layout tool that you prefer, then feel free to use it. For the purposes of this tutorial, I’ll use Adobe Illustrator. 

I recommend changing your artboard size to A4 and setting the units to millimeters, as this is what jsPDF uses. You'll also need to choose whether you want your certificate to be in layout or portrait orientation. I'm using landscape.

Certificate artboard settings in Adobe Illustrator - A4, millimeters, and landscape settings

With your artboard open, it’s time to design the certificate itself. Add your graphics and text to match your company or course branding. For this tutorial, I’m just using a slightly modified certificate that I downloaded from freepik.

PDF certificate screenshot

Notice that I left a placeholder for the person’s name and the date. We will dynamically add this information depending on who is generating the certificate and when they’re generating the certificate.

Once you’ve designed your certificate, export it as an image file. I’ve found that it works best to export it larger than it needs to be so that it looks crisp in the final PDF. Particularly, I set the width for this landscape-oriented certificate to 1600px and export it as a PNG.

Save the image file somewhere safe — we will need to put it in our published eLearning output folder later in the tutorial.

Collect Dynamic Info from the eLearning Course

Now it’s time to collect the dynamic info from our eLearning authoring tool of choice. We need to enter a text input box so that the user can enter their name, which will appear on the certificate.

In Articulate Storyline 360, we do this by going to the Insert tab, selecting Input, and then selecting Text Entry Field.

Storyline screenshot showing insert tab, input button, text entry field

Draw the text entry field on the slide, then add the rest of your design elements. You’ll also need to add a button named “Download Certificate” or something similar.

Download PDF certificate screen in Storyline

When the user enters their name in the text entry field that you added, it gets stored as a variable. Let’s open the variable manager and change the variable’s name from “TextEntry” to something more descriptive, such as “uName”.

If you’re adding additional dynamic information to the PDF (for example, for a PDF workbook or job aid), then you will want to collect and store that information in additional authoring tool variables.

Use jsPDF to Generate the PDF Certificate

Once your Storyline file is set up to capture the user’s name, we need to add the JavaScript that will generate the certificate. We’ll do this using jsPDF 1.5.3, which is an open source JavaScript to PDF library. You do not need to download the library — we will access it via a CDN by adding a script tag to our final Storyline ouput folder later in the tutorial.

I suggest writing the code in this section with a code editor, such as Visual Studio Code. Later in the tutorial I will show you how to execute the code via an "Execute JavaScript" trigger in Storyline.

I will walk through the code as we add it, then I’ll post the final, commented code at the bottom of this section. Feel free to copy and paste, but make sure you replace the values that need to change for your specific implementation.

So, now that we’re ready to start adding code, the first thing we need to do is capture the date. We can do this with the following JavaScript:

{% c-block language="js" %}
var date = new Date();
var dd = String(date.getDate()).padStart(2, '0');
var mm = String(date.getMonth() + 1).padStart(2, '0'); 
var yyyy = date.getFullYear();
date = mm + '/' + dd + '/' + yyyy;
{% c-block-end %}

Now we have a variable named “date” that stores the current date in the month/day/year format. If you need to change this to the day/month/year format, you can swap the “mm” and “dd” in the last line of code.

Next, we’ll collect the user’s name from Storyline with the following code:

{% c-block language="js" %}
var player = GetPlayer();
var name = player.GetVar("uName");
{% c-block-end %}

If you named the Storyline variable that holds the user’s name something other than “uName”, then you need to change it accordingly in the code above. These variable names are case sensitive.

Now we have a JavaScript variable called “name” that holds the user’s name.

This is where the code will get slightly more confusing, but you don’t need to understand it to use it. We’re going to use methods from the jsPDF library to initiate the PDF build, like so:

{% c-block language="js" %}
var doc = new jsPDF({
  orientation: 'landscape'
})
{% c-block-end %}

If your certificate is in portrait orientation, then simply remove the “orientation: ‘landscape’" line of code from the snippet above.

Next, we need to tell jsPDF that we’re including an image in the PDF. This is the image that you designed earlier, and it will serve as the background for the PDF.

{% c-block language="js" %}
var img = new Image;
img.onload = function() {
    doc.addImage(this, 0, 0, 297, 210);
{% c-block-end %}

As you can see above, the doc.addImage() function takes several arguments (in the following order):

  1. The image to add (we will add the source for this image later in the code)
  2. The x-coordinate to start displaying the image
  3. The y-coordinate to start displaying  the image
  4. The width of the image (in millimeters)
  5. The height of the image (in millimeters)

Naturally, if your certificate is in portrait orientation, then you’ll want to swap the 297 and 210 in the code above.

Next, let's add the user’s name to the certificate. We do this by setting the font size, text color, and font, then we add the text itself.

We set the font size with the setFontSize() method. It takes one argument: the font size in pixels.

{% c-block language="js" %}
doc.setFontSize(60);
{% c-block-end %}

We set the text color with the setTextColor() method. It takes the RGB color code as its arguments: 

{% c-block language="js" %}
doc.setTextColor(0, 0, 0);
{% c-block-end %}

We set the font with the setFont() method. If the font is one of the standard PDF fonts, then you only need to include one argument with the setFont() method: the name of the font itself. For example:

{% c-block language="js" %}
doc.setFont('Courier');
{% c-block-end %}

The 14 standard PDF fonts are as follows:

  • Courier
  • Courier-Bold
  • Courier-BoldOblique
  • Courier-Oblique
  • Helvetica
  • Helvetica-Bold
  • Helvetica-BoldOblique
  • Helvetica-Oblique
  • Symbol
  • Times-Roman
  • Times-Bold
  • Time-Italic
  • Time-BoldItalic
  • ZapfDingbats

However, since I want to use Lato, which is not a standard font, I have to include two arguments with the setFont() method: both the font and the style. This will not work unless you follow the steps in this tutorial: How to Use Custom Fonts with jsPDF.

{% c-block language="js" %}
doc.setFont('Lato-Black', 'bold');
{% c-block-end %}

So, if you plan to use a non-standard font, please pause now and complete the linked tutorial before continuing. Once you have the JavaScript files for your custom fonts, you are ready to continue.

Finally, we add the text with the text() method.

{% c-block language="js" %}
doc.text(name, (doc.internal.pageSize.width / 2), 120, null, null, 'center');
{% c-block-end %}

This text() method takes several arguments, in the following order:

  1. The text to add (in this case we pass the “name” variable, which holds the users name)
  2. The x-coordinate where the text should be placed (in this case we use a function that returns the middle point of the PDF)
  3. The y-coordinate where the text should be placed
  4. The width of the text box (we let the text box autosize, so we pass null as a value)
  5. The height of the text box (we let the text box autosize, so we pass null as a value)
  6. The alignment of the text (in this case, we want the text to be centered)

If you want the user's name to be centered on the certificate, then you can use the function for the x-coordinate that I used above. However, you will need to find the appropriate y-coordinate to place the text.

I recommend finding the x- and y-coordinates that you want to place your text on by using the graphic design tool that you used to create the certificate.

For example, since I am using Adobe Illustrator and need to identify the y-coordinate for my text, I will draw a line from the top of my artboard to point where I want the text to originate from. I then take the height of that line and plug it into the text() method as the y-coordinate (just as I did in the code above).

If you need the user's name in a different location, which you likely will, then you need to take the same approach with your certificate. And don't worry — I will show you how you can test this later in the tutorial.

Use line to measure height in Adobe Illustrator screenshot
Measure the height adobe illustrator sidebar screenshot

If you’ve added that code successfully, then it’s time to use the same treatment to add the date. If you want to use a different font size, font, or color for the new text, then you need to set it again using the appropriate methods. You can see my implementation of this here:

{% c-block language="js" %}
doc.setFont('Lato-Regular', 'normal');
doc.setFontSize(15);
doc.text(date, (doc.internal.pageSize.width / 2), 172, null, null, 'center');
{% c-block-end %}

This time, we used the “normal” version of the font and a smaller font size to place the date on the appropriate line.

We’re almost to the finish line. Now we need to tell the jsPDF library that it should save the certificate as a PDF:

{% c-block language="js" %}
  doc.save("Certificate.pdf");
};
img.crossOrigin = ""; 
{% c-block-end %}

You should change the “Certificate.pdf” code above to whatever you’d like your certificate to be called when the user downloads it.

Next, we need to tell code where it should pull the image from. This will be the name of the image file that you exported:

{% c-block language="js" %}
img.src = "certificate.png";
{% c-block-end %}

Change "certificate.png" to whatever you named your image file.

And there we have it! All together, my code is included below. Note that you will need to change some information on the commented lines so that it works for your certificate and needs. 

{% c-block language="js" %}
var date = new Date();
var dd = String(date.getDate()).padStart(2, '0');
var mm = String(date.getMonth() + 1).padStart(2, '0'); 
var yyyy = date.getFullYear();
date = mm + '/' + dd + '/' + yyyy;
var player = GetPlayer();
var name = player.GetVar("uName"); /* Replace uName with the Storyline variable holding the user's name */
var doc = new jsPDF({
  orientation: 'landscape' /* Remove this line of code if your certificate is in portrait orientation */
})
var img = new Image;
img.onload = function() {
 doc.addImage(this, 0, 0, 297, 210);
 doc.setFontSize(40); /* Set the font size by changing the number between the parentheses */
  doc.setTextColor(0, 0, 0); /* Change the RGB text color by changing the numbers between the parentheses */
  doc.setFont('Lato-Black', 'bold');
  doc.text(name, (doc.internal.pageSize.width / 2), 120, null, null, 'center'); /* This tells the PDF to add text to the page. The first argument is the text to add (in this case a JavaScript variable), the second is the x-coordinate (in this case we’re using a function to find a middle point for the document), the third is the y-coordinate (in millimeters), the fourth and fifth arguments are null, and the sixth argument says that the text should be centered */
   doc.setFont('Lato-Regular', 'normal');
   doc.setFontSize(15);
   doc.text(date, (doc.internal.pageSize.width / 2), 172, null, null, 'center'); /* See above for the full explanation of the doc.text() function */
   doc.save("Certificate.pdf"); /* Swap out ‘Certificate’ with what you want your certificate to be named */
  };
img.crossOrigin = "";  
img.src = "certificate.png"; /* Change the file name between these quotes to the file that you exported as the base certificate */
{% c-block-end %}

Once you’ve replaced all of the key pieces in the code above so that it fits with your project, it’s time to paste this code into a Storyline “Execute JavaScript” trigger.

We’ll execute the trigger when the user selects the “Generate Certificate” button.

Execute JavaScript trigger in Storyline screenshot

Publish and Modify the eLearning Output

Now it's time to publish the course. For the purposes of this tutorial, we’re going to publish the course as an HTML5 package.

Go to the Home tab and select Publish. Then, select the Web tab on the left and press the blue Publish button at the bottom.

Once it’s done publishing, select the Open button to open the published output folder.

Now you need to move your custom font JavaScript files (generated by following the steps in this tutorial) and the certificate image file to the published output folder. If you're not using any custom fonts, then you only need to add the certificate image file.

With these files in our published output folder, we now need to tell the course that it has those files available. We can do this by opening the story.html file (or story_html5.html file if you have an older version of Storyline) with our code or text editor of choice.

Simply right click the story.html file, select Open with, then select your code editor.

With the file open, scroll down to the bottom and find the closing body tag, which will look like this:

{% c-block language="markup" %}
</body>
{% c-block-end %}

Right above that line of code, we need to add some script tags to make the jsPDF library and font files available.

It should look like this: (If you are not using any custom fonts, then you only need to add the first script tag.)

{% c-block language="markup" %}
  <script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/1.5.3/jspdf.debug.js" integrity="sha384-NaWTHo/8YCBYJ59830LTz/P4aQZK1sS0SneOgAvhsIl3zBu8r9RevNg5lHCHAuQ/" crossorigin="anonymous"></script>
  <script src="Lato-Black-bold.js"></script>
  <script src="Lato-Regular-normal.js"></script>
</body>
{% c-block-end %}

Here is a screenshot from my story.html file:

Once you save this file, you need to publish it and test it on a live web server. It will not work if you open it locally on your computer. I recommend publishing to Amazon S3 for testing purposes (you can view my tutorial for how to do this here).

With the live link open, enter your name in the text box and then select the Generate Certificate button. If it doesn't work or if the text is in the wrong location, you can refresh the page, enter your name in the text box, then try executing the code from the console (instead of clicking the button). This lets you test iterations of your code without having to publish it and upload it again from Storyline.

You can access the console by pressing F12. From there, just paste in the JavaScript that you were executing from your button, make changes as needed, and press the enter key. Continue refreshing the page, entering your name, and executing your code from the console as needed until you get it right.

After it looks great, you can copy the latest code you were using in the console and add it to the Storyline course when the user selects the button. Republish and you're good to go!

Conclusion

As you can see, you can use this approach to generate PDF certificates, job aids, and dynamic workbooks from an eLearning course.

If you need a hand following along with this tutorial, then you can feel free to ask questions in my instructional design + eLearning Slack channel. Access is free for all mailing list subscribers. 

On the other hand, If you or your company would like to outsource the development of a dynamic PDF solution, then please contact me to request a quote.

Featured Tutorials

View all tutorials