<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Chris</title>
    <description>The latest articles on DEV Community by Chris (@chrisgordon256).</description>
    <link>https://dev.to/chrisgordon256</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F861486%2F30d37c07-510d-4bdd-9a15-09ef655b52d3.png</url>
      <title>DEV Community: Chris</title>
      <link>https://dev.to/chrisgordon256</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/chrisgordon256"/>
    <language>en</language>
    <item>
      <title>Generate invoice PDF file using HTML template</title>
      <dc:creator>Chris</dc:creator>
      <pubDate>Tue, 05 Sep 2023 13:24:26 +0000</pubDate>
      <link>https://dev.to/chrisgordon256/generate-invoice-pdf-file-using-html-template-481f</link>
      <guid>https://dev.to/chrisgordon256/generate-invoice-pdf-file-using-html-template-481f</guid>
      <description>&lt;p&gt;Today, I'll walk you through the process of generating an invoice PDF file for your backend app or custom script which could be run from the command line. Let's get started! 🎉&lt;/p&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://nodejs.org/"&gt;Node.js&lt;/a&gt; programming language will be used for simplicity.&lt;br&gt;
&lt;a href="https://handlebarsjs.com/"&gt;Handlebars&lt;/a&gt; template engine to separate data from the presentation.&lt;br&gt;
&lt;a href="https://html2pdf.app/"&gt;html2pdf.app&lt;/a&gt; to convert HTML to PDF, but as an alternative Puppeteer can be used also (you can find a complete tutorial &lt;a href="https://html2pdf.app/blog/how-to-convert-html-to-pdf-with-puppeteer/"&gt;How to convert HTML to PDF with puppeteer&lt;/a&gt;).&lt;/p&gt;
&lt;h2&gt;
  
  
  Project structure
&lt;/h2&gt;

&lt;p&gt;Let's assume we are creating a new project "generate-invoice", first Create a directory using the command &lt;code&gt;mkdir generate-invoice&lt;/code&gt;. Then initialize a Node.js project by entering the command &lt;code&gt;npm init&lt;/code&gt; and provide all the necessary information.&lt;/p&gt;

&lt;p&gt;Now we need to install dependencies, which will be used. For that run the command &lt;code&gt;npm i handlebars axios&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Having all the needed dependencies, let's create a conversion file using the command &lt;code&gt;mkdir src &amp;amp;&amp;amp; touch src/generate.js&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Now we need to store the template where the HTML code will be provided. Create a templates directory and invoice.html file for that with the command &lt;code&gt;mkdir templates &amp;amp;&amp;amp; touch templates/invoice.html&lt;/code&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This simple project structure is enough to start writing the code. Your project should look like this tree below.&lt;br&gt;
&lt;/p&gt;


&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;├── package-lock.json
├── package.json
├── node_modules
├── src
│   └── generate.js
└── templates
    └── invoice.html
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Prepare the template
&lt;/h2&gt;

&lt;p&gt;Before diving into the conversion process, you'll need to create an HTML template for your invoice. This template will define the layout, content, and styling of your PDF invoice.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;There are many invoice HTML templates you can find on Google. I am going to use an already created one, whose code source you can find &lt;a href="https://github.com/html2pdfapp/examples/blob/main/assets/invoice.html"&gt;here&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In the end, it should look the following:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--XUxs7p3_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zpp2fknes7xm3kzg1q3w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--XUxs7p3_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zpp2fknes7xm3kzg1q3w.png" alt="Image description" width="800" height="885"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Feel free to customize the HTML template to match your branding and invoicing needs. You can update fonts, and colours, add your company logo, and include any necessary details like invoice number, customer information, etc.&lt;/p&gt;

&lt;p&gt;Put your template HTML code into the &lt;code&gt;templates/invoice.html&lt;/code&gt; file and let's move to the next step.&lt;/p&gt;

&lt;h2&gt;
  
  
  Convert HTML to PDF
&lt;/h2&gt;

&lt;p&gt;First, we need to add needed dependencies to the conversion script.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import fs from 'fs';
import Handlebars from 'handlebars';
import axios from 'axios';
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we can load the invoice HTML code into the Handlebars template.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const invoice = fs.readFileSync('./assets/invoice.html', 'utf8');
const template = Handlebars.compile(invoice);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Also, we need to set parameters which will be binded into the template, they can come from various places in your real project. For example database, Excel file, command line arguments and so on. I will define those parameters in the script directly for simplicity.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const params = {
    invoiceNr: 'H2P202307-01711',
    billTo: 'Anna Smith',
    invoiceDate: (new Date()).toDateString(),
    paymentDue: (new Date()).toDateString(),
    orderId: 112233,
    items: [
        {description: 'Domain registration', quantity: 2, price: '$10', total: '$20'},
        {description: 'Web hosting', quantity: 1, price: '$15', total: '$15'},
        {description: 'Consulting', quantity: 1, price: '$500', total: '$500'},
    ],
    subTotal: '$535',
    tax: '$53.5',
    total: '$588.5',
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we can process the template by passing the parameters and get the result - the final HTML code which will be converted to the PDF document.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const html = template(params);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There are multiple options for how to convert HTML to PDF, one could be by using open-source projects like &lt;a href="https://pptr.dev/"&gt;Puppeteer&lt;/a&gt; or &lt;a href="https://wkhtmltopdf.org/"&gt;wkhtmltopdf&lt;/a&gt;. I wrote a separate post &lt;a href="https://html2pdf.app/blog/how-to-convert-html-to-pdf-with-puppeteer/"&gt;How to convert HTML to PDF using Puppeteer&lt;/a&gt;, but now for simplicity, I going to use html2pdf.app. Its free plan gives 100 credits per month, excellent!&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;To register and get the free API key use the link: &lt;a href="https://dash.html2pdf.app/registration"&gt;https://dash.html2pdf.app/registration&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Once you have an API Key, let's finish the conversion part.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const apiKey = '******************'; // API key from https://html2pdf.app

const response = await axios.post('https://api.html2pdf.app/v1/generate', {
    html,
    apiKey,
}, {responseType: 'arraybuffer'});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To send the HTML code to the PDF conversion API there are only a few lines of code. Now what needs to be done is to save the response. For that add the code line below to your script.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;fs.writeFileSync('./assets/invoice.pdf', response.data);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The complete conversion script code looks as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import fs from 'fs';
import Handlebars from 'handlebars';
import axios from 'axios';

const invoice = fs.readFileSync('./assets/invoice.html', 'utf8');
const template = Handlebars.compile(invoice);
const params = {
    invoiceNr: 'H2P202307-01711',
    billTo: 'Anna Smith',
    invoiceDate: (new Date()).toDateString(),
    paymentDue: (new Date()).toDateString(),
    orderId: 112233,
    items: [
        {description: 'Domain registration', quantity: 2, price: '$10', total: '$20'},
        {description: 'Web hosting', quantity: 1, price: '$15', total: '$15'},
        {description: 'Consulting', quantity: 1, price: '$500', total: '$500'},
    ],
    subTotal: '$535',
    tax: '$53.5',
    total: '$588.5',
};

const html = template(params);
const apiKey = 'd3a0264f70864...'; // get api key on https://html2pdf.app

const response = await axios.post('https://api.html2pdf.app/v1/generate', {
    html,
    apiKey,
}, {responseType: 'arraybuffer'});

fs.writeFileSync('./assets/invoice.pdf', response.data);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;You can find it on GitHub also &lt;a href="https://github.com/html2pdfapp/examples/blob/main/src/generate-invoice.js"&gt;https://github.com/html2pdfapp/examples/blob/main/src/generate-invoice.js&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;I like not to mix business logic or data with the presentation layer, and currently, there is a much clearer solution when we have a template separated from the data.&lt;/p&gt;

&lt;p&gt;The simplicity of html2pdf.app API and its free plan allow us to save time and only with a few lines of code, we have the converted PDF file you can store it somewhere in the cloud or project directory.&lt;/p&gt;

&lt;p&gt;Happy coding!&lt;/p&gt;

</description>
      <category>invoice</category>
      <category>pdf</category>
      <category>generate</category>
      <category>template</category>
    </item>
    <item>
      <title>How to convert HTML to PDF using Puppeteer</title>
      <dc:creator>Chris</dc:creator>
      <pubDate>Fri, 21 Jul 2023 19:29:07 +0000</pubDate>
      <link>https://dev.to/chrisgordon256/convert-html-to-pdf-using-puppeteer-2c57</link>
      <guid>https://dev.to/chrisgordon256/convert-html-to-pdf-using-puppeteer-2c57</guid>
      <description>&lt;p&gt;Whether you're looking to generate invoices, create reports, or preserve web content for offline use, &lt;a href="https://pptr.dev/"&gt;Puppeteer&lt;/a&gt; is a powerful tool that can automate the process seamlessly. In this guide, we will explore how to convert HTML to PDF using Puppeteer, an open-source Node.js library developed by Google.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting Up Puppeteer
&lt;/h2&gt;

&lt;p&gt;To get started, you'll need to have Node.js installed on your machine. Open your terminal or command prompt and create a new directory for your project. Navigate into the project directory and initialize a new Node.js project by running the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm init -y
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, install Puppeteer as a dependency by executing the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install puppeteer
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Puppeteer will now be added to your project, allowing you to programmatically control a headless Chrome or Chromium browser.&lt;/p&gt;

&lt;h2&gt;
  
  
  Writing the conversion script
&lt;/h2&gt;

&lt;p&gt;Create a new JavaScript file, such as &lt;code&gt;convert-html-to-pdf.js&lt;/code&gt;, in your project directory. Open the file in your preferred text editor and begin by importing the Puppeteer library:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const puppeteer = require('puppeteer');
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Initializing Puppeteer and Converting HTML to PDF
&lt;/h2&gt;

&lt;p&gt;Inside the &lt;code&gt;convert-html-to-pdf.js&lt;/code&gt; file, add the following code to initialize Puppeteer and convert the HTML to PDF:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(async () =&amp;gt; {
  try {
    const browser = await puppeteer.launch();
    const page = await browser.newPage();
    await page.goto('file:///path/to/your/html/file.html', { waitUntil: 'networkidle0' });

    // To use normal CSS instead of only print styles
    await page.emulateMediaType('screen');

    await page.pdf({ path: 'output.pdf', format: 'A4' });

      console.log('Conversion complete. PDF file generated successfully.');

      await browser.close();
    } catch (error) {
      console.error('An error occurred:', error);
    }

})();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The example shows how to convert an existing html file to the pdf, but you might be needed to convert html code which could be passed as a parameter to the puppeteer. In this case function &lt;code&gt;page.setContent()&lt;/code&gt; should be used. Check the example below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const html = '&amp;lt;html...';
await page.setContent(html, { waitUntil: 'networkidle0' });
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Converting URL to PDF
&lt;/h2&gt;

&lt;p&gt;You can easily update the code to convert an URL instead of HTML or file, by passing the URL to the &lt;code&gt;page.goto&lt;/code&gt; method:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;await page.goto('https://example.com', { waitUntil: 'networkidle0' });
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;It is important to understand &lt;code&gt;waitUntil&lt;/code&gt; parameter and it's values to choose a proper one.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;load&lt;/code&gt;: when load event is fired.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;domcontentloaded&lt;/code&gt;: when the DOMContentLoaded event is fired.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;networkidle0&lt;/code&gt;: when there are no more than 0 network connections for at least 500 ms.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;networkidle2&lt;/code&gt;: when there are no more than 2 network connections for at least 500 ms.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For more detailed information, which options can be passed to the &lt;code&gt;puppeteer.goto&lt;/code&gt; method check the puppeteer &lt;a href="https://pptr.dev/api/puppeteer.page.goto#remarks"&gt;documentation&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Break down the code
&lt;/h2&gt;

&lt;p&gt;We have created an async function using an immediately invoked function expression (IIFE) to ensure proper execution. Inside the function, we launched a new instance of the Puppeteer controlled browser.&lt;/p&gt;

&lt;p&gt;We open a new page and navigate to the desired HTML file using the &lt;code&gt;page.goto()&lt;/code&gt; method. Make sure to replace 'file:///path/to/your/html/file.html' with the actual path to your HTML file. By specifying &lt;code&gt;{ waitUntil: 'networkidle0' }&lt;/code&gt;, we ensure that the page is fully loaded before generating the PDF.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;It is necessary to execute method: &lt;code&gt;page.emulateMediaType('screen');&lt;/code&gt; to have fully loaded CSS.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Finally, we call &lt;code&gt;page.pdf()&lt;/code&gt; to convert the HTML to PDF and specify the output path and format. Adjust the path and format properties as needed. After successful conversion, we log a message and close the browser instance.&lt;/p&gt;

&lt;h2&gt;
  
  
  Running the conversion script
&lt;/h2&gt;

&lt;p&gt;Save the &lt;code&gt;convert-html-to-pdf.js&lt;/code&gt; file, navigate to your project directory in the terminal or command prompt, and run the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;node convert-html-to-pdf.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Puppeteer will launch a headless browser, load the HTML file, convert it to PDF, and save the output as output.pdf in the project directory.&lt;/p&gt;

&lt;h2&gt;
  
  
  Using html2pdf.app API
&lt;/h2&gt;

&lt;p&gt;Managing Puppeteer can be chalanging task, especially if you need to scale up the application. Huge number of the requests can break the server performance since PDF conversion requires quite many resources.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Make your life easier by using &lt;a href="https://html2pdf.app/documentation/"&gt;html to pdf&lt;/a&gt; API to convert PDFs.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Following code shows how it is simple todo with our api:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import axios from 'axios';
import fs from 'fs';

axios.post('https://api.html2pdf.app/v1/generate', {
  html: 'https://example.com',
  apiKey: '{your-api-key}',
}, {responseType: 'arraybuffer'}).then((response) =&amp;gt; {
  fs.writeFileSync('./document.pdf', response.data);
}).catch((err) =&amp;gt; {
  console.log(err.message);
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;By following the steps outlined in this guide, you can easily convert HTML files to PDF using Puppeteer. This versatile library opens up a world of possibilities for automating document generation, report creation, and more.&lt;/p&gt;

&lt;p&gt;If you do not want to struggle with some edge cases and have a fast result, try already built in solutions to convert PDFs like &lt;a href="https://html2pdf.app"&gt;html2pdf.app&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Happy coding!&lt;/p&gt;

</description>
      <category>programming</category>
      <category>tutorial</category>
      <category>node</category>
      <category>webdev</category>
    </item>
    <item>
      <title>My journey of making a side project which makes passive incomes</title>
      <dc:creator>Chris</dc:creator>
      <pubDate>Sun, 15 May 2022 18:41:09 +0000</pubDate>
      <link>https://dev.to/chrisgordon256/my-journey-of-making-a-side-project-which-makes-passive-incomes-31h8</link>
      <guid>https://dev.to/chrisgordon256/my-journey-of-making-a-side-project-which-makes-passive-incomes-31h8</guid>
      <description>&lt;p&gt;Hello, I want to share my story of how I have created my side project of &lt;a href="https://html2pdf.app"&gt;html2pdf.app&lt;/a&gt;. You can see from the domain that it is the HTML to PDF conversion API.&lt;/p&gt;

&lt;p&gt;Working as a full-time developer I was living quite a normal and good life. But one thought from time to time was coming to my head - creating my own project which makes money.&lt;/p&gt;

&lt;p&gt;I decided to do something for a very specific niche, to avoid high competitiveness and where I have some experience. So I came up with the idea that a &lt;a href="https://html2pdf.app"&gt;HTML to PDF API&lt;/a&gt; conversion service online would be a great one to start with.&lt;/p&gt;

&lt;p&gt;Almost in every company where I worked, I had to implement some PDF generation feature and in old times it was very challenging to do.&lt;/p&gt;

&lt;h2&gt;
  
  
  How did I start
&lt;/h2&gt;

&lt;p&gt;When I was starting a new project I decided to learn something new at the same time. Also if my project would not be successful at least I could learn something useful.&lt;/p&gt;

&lt;p&gt;Being a PHP developer for a long time I had also experience with JavaScript and at that time the NodeJS framework was quite interesting to me. Also, I knew that there is a Headless Chrome engine which is very convenient to use with the Puppeteer library.&lt;/p&gt;

&lt;p&gt;I noticed that using Headless Chrome converted PDFs are high quality and quite similar compared to the HTML. I understood that Headless Chrome has the power and I need to leverage it!&lt;/p&gt;

&lt;p&gt;Since I have a full-time job and family, it was a challenge for me to find time to develop my side project. So I started to work on weekends, very slowly but I was moving forward.&lt;/p&gt;

&lt;p&gt;NodeJS framework was unfamiliar to me and took significantly more time to do the same things which I could do with PHP. I did not know even how to use the debugger, or how to structure my app from the beginning. But after some time I was feeling more comfortable in this stack.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tech stack
&lt;/h2&gt;

&lt;p&gt;These are technologies that I have chosen to use. One thing which I would change is perhaps choosing golang instead of NodeJS.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;NodeJS/TypeScript + ExpressJS/NestJS frameworks;&lt;/li&gt;
&lt;li&gt;Mysql for permanent data storage;&lt;/li&gt;
&lt;li&gt;MongoDB for storing conversions logs;&lt;/li&gt;
&lt;li&gt;Redis for caching;&lt;/li&gt;
&lt;li&gt;RabbitMQ for async jobs and async communication between microservices;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Also, I integrated third-party services like sentry, mailgun, stripe, mailerlite which are very helpful and make developer's life easier.&lt;/p&gt;

&lt;h2&gt;
  
  
  Microservices architecture
&lt;/h2&gt;

&lt;p&gt;Since I chose microservices architecture things became even more complicated. It took a bit of time to set up multiple services to make communication among them proper.&lt;/p&gt;

&lt;p&gt;So from my practice, I would suggest once you are doing a startup/side project and are focusing on how to make money not gain experience in a new field, skip new/fancy technologies, and create a monolith system, which could be scaled further.&lt;/p&gt;

&lt;p&gt;The diagram below illustrates the relations between the microservices of my project.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--4kZcTAdD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0md31fkmxv5mubn7lfox.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--4kZcTAdD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0md31fkmxv5mubn7lfox.png" alt="HTML to PDF API microservices relations schema" width="667" height="497"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Where to get customers?
&lt;/h2&gt;

&lt;p&gt;So finally I launched my service totally free. My plan was to get new customers and make sure that my service is useful to somebody. And actually, it was useful, new clients were registering, and I do not know how I became on the first page of a Google Search by keyword “HTML to pdf API”. I also set up Google AdWords to get more new customers.&lt;/p&gt;

&lt;h2&gt;
  
  
  First paid customer
&lt;/h2&gt;

&lt;p&gt;After some time I noticed that customers who are using the HTML to PDF conversion service are very grateful, some of them even asked how to send money for using the service. So I decided to monetize the service and establish a small company to make everything legal.&lt;/p&gt;

&lt;p&gt;I left a free plan for the clients with limited conversions per month and also created paid plans, and things started moving forwards. I was very happy when I could cover server expenses and pay taxes without using my own money.&lt;/p&gt;

&lt;p&gt;Currently, I have over 50 paying clients, not many but still a good achievement for me making passive incomes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Challenges I faced
&lt;/h2&gt;

&lt;p&gt;First of all, NodeJS has no static typing so it was very uncomfortable for me, even an IDE didn’t show autocompletion. &lt;/p&gt;

&lt;p&gt;I was struggling with this for some time and decided to use TypeScript, so rewrote all the code in this language. It took some time to rewrite and set up the project to use TypeScript but it was definitely worth it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Headless Chrome scalability and AWS Lambda
&lt;/h3&gt;

&lt;p&gt;Another challenge I encountered was scalability because I was using a headless chrome engine just directly installed into the server where applications run.&lt;/p&gt;

&lt;p&gt;From time to time I noticed that one instance of Headless Chrome sometimes crashed when there are more requests. So after some attempts to solve this problem, I decided to try the AWS Lambda function and the results were stunning.&lt;/p&gt;

&lt;p&gt;It scales automatically and is able to handle high loads. Setting up a working Lambda function and Puppeteer library was a bit challenging but I managed it successfully.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;As I wanted to learn and develop a project at the same time, I decided to use microservices architecture to gather more experience and this was a mistake.&lt;/p&gt;

&lt;p&gt;I spent a lot of time making microservices work and increased the complexity of the whole infrastructure. If I could give a suggestion for someone who is starting a startup I wouldn’t recommend chasing cutting-edge technologies and definitely do not start with microservices.&lt;/p&gt;

&lt;p&gt;Create an MVP first, and check how your audience is reacting to your product and what changes you need to make after the feedback. Then when you see that your project could be beneficial do some cleanups, refactoring, splitting things into microservices, etc.&lt;/p&gt;

&lt;p&gt;No doubts, I learned a lot of new things and got an experience that I could not get at work working on regular projects.&lt;/p&gt;

&lt;p&gt;There are many things that could be improved and make service better, but overall, I am happy to have created this project and had this experience.&lt;/p&gt;

&lt;p&gt;I feel like I am growing as a professional by learning new things, and solving problems at the same time making my side project better.&lt;/p&gt;

&lt;p&gt;That was my story, hope you enjoyed reading it. If somebody is interested more to know technical details I could answer with pleasure in the comments.&lt;/p&gt;

</description>
      <category>pdf</category>
      <category>sideprojects</category>
      <category>api</category>
      <category>startup</category>
    </item>
  </channel>
</rss>
