Introduction
Page Builder is a tool used to create pages, similar to Microsoft Word, but with Svelte. This means pages can be printed as letter size pages or saved as a PDF, and can be completely customized with HTML and CSS.
The Motivation
The project idea came from creating my resume. When I would use Google Docs / Microsoft Word, I often had a hard time getting the format exactly how I wanted - for example, having multiple items separated equally and aligned properly. This however could be done pretty simply with CSS flexboxes.
Since I knew Svelte, I decided to just write my resumes in HTML and CSS, and create resuable components for sections. Now, I have full control over the look of the resume, and iterations have become faster.
Implementation
While this project post will not have a link to my current repository, I will provide the implementation details.
Creating a Page
The first step is to create a Page component. This allows creating pages in a designated size.
<script lang="ts">
import type { Snippet } from 'svelte';
interface Props {
height?: string;
width?: string;
children?: Snippet;
}
// defaults to standard letter size
let { height = '11in', width = '8.5in', children }: Props = $props();
</script>
<div class="relative bg-white p-8 text-[16px]" style="height: {height}; width: {width};">
{@render children?.()}
</div> Pretty simple right? Now we just wrap whatever content we in the Page Component.
<script lang="ts">
import Page from '$lib/page.svelte';
</script>
<Page>
<!-- Content goes here -->
</Page> Printing
Just because we defined the size of the Page component, it does not mean that only that will be printed or saved as a PDF. Browsers will still try to print the entire html body - here is how we fix that.
The printing size of a page can actually be defined in the app.css using the @page css at-rule.
"The
@pageat-rule is a CSS at-rule used to modify different aspects of printed pages." - MDN
@page {
size: letter;
/* OR */
/* size: 11in 8.5in; */
margin: 0;
} This should work if you only have Page components in your app - however, you may have other text on other areas in the app that you do not want printed. We can stop elements from being printed using the css @media at-rule and the print media type.
@media print {
.noprint {
display: none;
}
} You can now use the noprint class on an element to prevent it from being printed.