Practical Svelte: Create Performant Applications with the Svelte Component Framework 9781484273739, 9781484273746, 1484273737

Learn to leverage the power of Svelte to produce web applications that are efficient and fast. This project-oriented boo

201 67 6MB

English Pages 340 [325]

Report DMCA / Copyright

DOWNLOAD PDF FILE

Table of contents :
Table of Contents
About the Author
About the Technical Reviewer
Acknowledgments
Introduction
Chapter 1: Getting Started
Introducing Svelte
Setting Up a Development Environment
So How Do We Get Svelte?
Creating Your First Application
Understanding What Happened
What Makes Svelte Different?
Browser Support
Setting Up Our Project
Reviewing the Changes Made
Exploring the Structure of Our Site
Setting the Background
Summary
Chapter 2: Creating Components
Understanding the Makeup of Components
Creating an Example Component
Building the Example Component
Reviewing the Code
Setting Expectations
Working Out the Architecture
Making a Start with App.svelte
Reviewing the Code Changes
Setting Up the Component Index
Creating the Header
Setting Up the Footer
Creating the Product Gallery
Building the Product Card
Reviewing the Code
Creating a Button Component
Adding the Cart
Breaking Apart the Code Used
Creating the Remaining Pages
File Formats and Svelte – A Note
Testing the Initial Site
Summary
Chapter 3: Managing State and Data
Why Is Data So Important in Svelte?
Passing and Setting Values in Code
Exploring the World of Props
Reviewing the Code
Making Use of Context in Svelte
Breaking Apart the Code
Creating and Maintaining Svelte Stores
Understanding the Code in Detail
Understanding the Differences
Adding Functionality to Our Site
Adding Props Support
Exploring the Changes
Adding New Functionality Using Stores
Breaking Apart the Code
Exploring Alternative Data Sources
Summary
Chapter 4: Controlling Logic
Creating If-Else Conditions
Breaking Apart the Code
Implementing Each Conditions
Exploring the Code
Removing the Right Item
Breaking Apart the Code in Detail
Fetching Content
Understanding the Changes Made
Exploring Existing Code in the Demo
Updating the Shop
Adding Login Functionality to Our Site
Understanding the Changes
Loading Products
Exploring the Code in Detail
An Epilogue – Improving the Placeholder Message
Summary
Chapter 5: Managing Events
The Theory of Reactivity
Choosing from Different Event Types
Creating Events
Understanding the Changes
Modifying Event Handlers
Exploring the Changes in Detail
Creating Events in Components
Forwarding Events
Breaking Apart the Changes
A Point of Note
Life Cycling Events in Svelte
Working with onMount
Exploring beforeUpdate
Understanding How It Works
Implementing Actions
Reworking the Code
Understanding What Happened
Adding Functionality to Our Site
Adding a Modal
Exploring Changes Made to Code
Exploring the Examples
Using the Plugin – An Epilogue
Summary
Chapter 6: Binding Elements
Creating Forms in Svelte
Catering for Different Form Elements
Working with Numeric Inputs
Using Checkbox Inputs
Handling Multiline Text Area Inputs
Selecting Choices
Dealing with Content Editable Fields
Binding and Managing Other Events
Building a Composite Example
Breaking the Code Apart
Managing Context
Understanding the Changes
Adding a Contact Form to Our Demo
Introducing Svelte-Yup
Laying the Groundwork
Building the Contact Form
Understanding the Code in Detail
Summary
Chapter 7: Adding Styles
Making Some Small Adjustments
Understanding Styling in Svelte
Adding Styling to the Front-End Demo
Updating the Global Stylesheet
Styling the Pages
Styling the Header and Footer
Styling the Buttons
Styling the Product Pages and Cart
Breaking Apart the Code Changes
Using a Style Preprocessor
Breaking the Code Apart
Taking Things Further
Summary
Chapter 8: Unit Testing and Svelte
Deciding Our Strategy
Browser Support
Setting Up the Test Environment
Understanding the Changes Made
Creating an Example Test
A Note About File Structure
Applying Principles to Our Project
Writing Tests for the Home Page
Breaking Apart the Changes Made
Testing the Remaining Content Pages
Reviewing the Code in Detail
Testing the Product Pages and Cart
Exploring the Changes
Debugging Svelte
Using Lighthouse
Summary
Chapter 9: Deploying Svelte
Doing Final Checks
Understanding the Deployment Process
Setting Up the Hosting Provider
Checking the Default Branch
Deploying Content to Production
Breaking Apart the Changes
Adding a Custom Domain Name
Breaking Apart the Code Changes
Taking It Further
Summary
Chapter 10: Working with External Libraries
Importing Libraries into Svelte
Testing Compatibility with Svelte
Exploring the Code in Detail
Working Client Side vs. Server Side
Why Is Svelte Different?
Adding a Payment Processor
Getting Prepared
Taking a First Look at the PayPal Demo
Adding PayPal to Our Front-End Site
Testing the Result
Reviewing the Changes Made
What About React?
Breaking Apart the Changes
Summary
Chapter 11: Animating Svelte
Auditing the Site
Learning a Language
Understanding How the Code Works
Reviewing the Types of Animation Options
Applying Easing Effects
Creating Custom Easing Effects in JavaScript
Exploring What Happened
Using Styles to Create Custom Easing Effects
Taking It Further
Using Svelte Libraries
Applying Animation to Our Project
Adding Animation to the Banner
Breaking Apart the Code Changes
Updating the Cart Action
Understanding the Changes Made
Iterating Through Pictures
Understanding What Happened
Summary
Chapter 12: Adapting for Sapper
Introducing... Sapper?
Migrating Our Project – Setting Expectations
Setting Up the Initial Site
Exploring the Code in Detail
Understanding the Structure of a SvelteKit Site
Updating the Layout
Understanding the Changes Made
Adding Pages
Understanding the Changes Made
Adding Product Gallery
Breaking the Code Apart
Adding Product Page
Understanding the Changes Made
Migrating Styles
Breaking Apart the Code
Testing the Site and Next Steps
Summary
Appendix: Getting Help
Index
Recommend Papers

Practical Svelte: Create Performant Applications with the Svelte Component Framework
 9781484273739, 9781484273746, 1484273737

  • 0 0 0
  • Like this paper and download? You can publish your own PDF file online for free in a few minutes! Sign Up
File loading please wait...
Citation preview

Practical Svelte Create Performant Applications with the Svelte Component Framework — Alex Libby

Practical Svelte Create Performant Applications with the Svelte Component Framework

Alex Libby

Practical Svelte: Create Performant Applications with the Svelte Component Framework Alex Libby BELPER, UK ISBN-13 (pbk): 978-1-4842-7373-9 https://doi.org/10.1007/978-1-4842-7374-6

ISBN-13 (electronic): 978-1-4842-7374-6

Copyright © 2022 by Alex Libby This work is subject to copyright. All rights are reserved by the Publisher, whether the whole or part of the material is concerned, specifically the rights of translation, reprinting, reuse of illustrations, recitation, broadcasting, reproduction on microfilms or in any other physical way, and transmission or information storage and retrieval, electronic adaptation, computer software, or by similar or dissimilar methodology now known or hereafter developed. Trademarked names, logos, and images may appear in this book. Rather than use a trademark symbol with every occurrence of a trademarked name, logo, or image we use the names, logos, and images only in an editorial fashion and to the benefit of the trademark owner, with no intention of infringement of the trademark. The use in this publication of trade names, trademarks, service marks, and similar terms, even if they are not identified as such, is not to be taken as an expression of opinion as to whether or not they are subject to proprietary rights. While the advice and information in this book are believed to be true and accurate at the date of publication, neither the authors nor the editors nor the publisher can accept any legal responsibility for any errors or omissions that may be made. The publisher makes no warranty, express or implied, with respect to the material contained herein. Managing Director, Apress Media LLC: Welmoed Spahr Acquisitions Editor: Louise Corrigan Development Editor: James Markham Coordinating Editor: Nancy Chen Cover designed by eStudioCalamar Cover image by Clark van der Beken on Unsplash (www.unsplash.com) Distributed to the book trade worldwide by Apress Media, LLC, 1 New York Plaza, New York, NY 10004, U.S.A. Phone 1-800-SPRINGER, fax (201) 348-4505, e-mail [email protected], or visit www. springeronline.com. Apress Media, LLC is a California LLC and the sole member (owner) is Springer Science + Business Media Finance Inc (SSBM Finance Inc). SSBM Finance Inc is a Delaware corporation. For information on translations, please e-mail [email protected]; for reprint, paperback, or audio rights, please e-mail [email protected]. Apress titles may be purchased in bulk for academic, corporate, or promotional use. eBook versions and licenses are also available for most titles. For more information, reference our Print and eBook Bulk Sales web page at http://www.apress.com/bulk-sales. Any source code or other supplementary material referenced by the author in this book is available to readers on GitHub via the book’s product page, located at www.apress.com/9781484273739. For more detailed information, please visit http://www.apress.com/source-­code. Printed on acid-free paper

This is dedicated to my family, with thanks for their love and support while writing this book.

Table of Contents About the Author��������������������������������������������������������������������������������������������������� xiii About the Technical Reviewer���������������������������������������������������������������������������������xv Acknowledgments�������������������������������������������������������������������������������������������������xvii Introduction������������������������������������������������������������������������������������������������������������xix Chapter 1: Getting Started���������������������������������������������������������������������������������������� 1 Introducing Svelte������������������������������������������������������������������������������������������������������������������������� 1 Setting Up a Development Environment��������������������������������������������������������������������������������������� 2 So How Do We Get Svelte?������������������������������������������������������������������������������������������������������ 3 Creating Your First Application������������������������������������������������������������������������������������������������������ 5 Understanding What Happened���������������������������������������������������������������������������������������������������� 8 What Makes Svelte Different?������������������������������������������������������������������������������������������������������� 9 Browser Support�������������������������������������������������������������������������������������������������������������������� 13 Setting Up Our Project���������������������������������������������������������������������������������������������������������������� 13 Reviewing the Changes Made����������������������������������������������������������������������������������������������� 15 Exploring the Structure of Our Site��������������������������������������������������������������������������������������������� 15 Setting the Background�������������������������������������������������������������������������������������������������������������� 18 Summary������������������������������������������������������������������������������������������������������������������������������������ 19

Chapter 2: Creating Components���������������������������������������������������������������������������� 21 Understanding the Makeup of Components�������������������������������������������������������������������������������� 21 Creating an Example Component������������������������������������������������������������������������������������������������ 22 Building the Example Component����������������������������������������������������������������������������������������� 23 Reviewing the Code��������������������������������������������������������������������������������������������������������������� 26 Setting Expectations������������������������������������������������������������������������������������������������������������������� 27 Working Out the Architecture������������������������������������������������������������������������������������������������ 28 v

Table of Contents

Making a Start with App.svelte��������������������������������������������������������������������������������������������������� 31 Reviewing the Code Changes������������������������������������������������������������������������������������������������ 33 Setting Up the Component Index������������������������������������������������������������������������������������������� 34 Creating the Header�������������������������������������������������������������������������������������������������������������������� 35 Setting Up the Footer������������������������������������������������������������������������������������������������������������������ 37 Creating the Product Gallery������������������������������������������������������������������������������������������������������� 39 Building the Product Card������������������������������������������������������������������������������������������������������ 41 Reviewing the Code��������������������������������������������������������������������������������������������������������������� 43 Creating a Button Component����������������������������������������������������������������������������������������������������� 44 Adding the Cart���������������������������������������������������������������������������������������������������������������������� 45 Breaking Apart the Code Used����������������������������������������������������������������������������������������������� 48 Creating the Remaining Pages���������������������������������������������������������������������������������������������������� 49 File Formats and Svelte – A Note������������������������������������������������������������������������������������������������ 49 Testing the Initial Site����������������������������������������������������������������������������������������������������������������� 49 Summary������������������������������������������������������������������������������������������������������������������������������������ 50

Chapter 3: Managing State and Data���������������������������������������������������������������������� 53 Why Is Data So Important in Svelte?������������������������������������������������������������������������������������������� 53 Passing and Setting Values in Code�������������������������������������������������������������������������������������������� 55 Exploring the World of Props������������������������������������������������������������������������������������������������������� 56 Reviewing the Code��������������������������������������������������������������������������������������������������������������� 58 Making Use of Context in Svelte������������������������������������������������������������������������������������������������� 59 Breaking Apart the Code�������������������������������������������������������������������������������������������������������� 61 Creating and Maintaining Svelte Stores�������������������������������������������������������������������������������������� 63 Understanding the Code in Detail������������������������������������������������������������������������������������������ 65 Understanding the Differences��������������������������������������������������������������������������������������������������� 66 Adding Functionality to Our Site������������������������������������������������������������������������������������������������� 68 Adding Props Support������������������������������������������������������������������������������������������������������������ 69 Exploring the Changes����������������������������������������������������������������������������������������������������������� 71 Adding New Functionality Using Stores�������������������������������������������������������������������������������� 71 Breaking Apart the Code�������������������������������������������������������������������������������������������������������� 73 vi

Table of Contents

Exploring Alternative Data Sources��������������������������������������������������������������������������������������������� 74 Summary������������������������������������������������������������������������������������������������������������������������������������ 76

Chapter 4: Controlling Logic����������������������������������������������������������������������������������� 77 Creating If-Else Conditions���������������������������������������������������������������������������������������������������������� 77 Breaking Apart the Code�������������������������������������������������������������������������������������������������������� 80 Implementing Each Conditions��������������������������������������������������������������������������������������������������� 81 Exploring the Code���������������������������������������������������������������������������������������������������������������� 83 Removing the Right Item������������������������������������������������������������������������������������������������������������� 84 Breaking Apart the Code in Detail������������������������������������������������������������������������������������������ 87 Fetching Content������������������������������������������������������������������������������������������������������������������������� 88 Understanding the Changes Made���������������������������������������������������������������������������������������� 92 Exploring Existing Code in the Demo������������������������������������������������������������������������������������������ 93 Updating the Shop���������������������������������������������������������������������������������������������������������������������� 94 Adding Login Functionality to Our Site���������������������������������������������������������������������������������� 94 Loading Products������������������������������������������������������������������������������������������������������������������� 97 An Epilogue – Improving the Placeholder Message������������������������������������������������������������ 100 Summary���������������������������������������������������������������������������������������������������������������������������������� 102

Chapter 5: Managing Events��������������������������������������������������������������������������������� 103 The Theory of Reactivity����������������������������������������������������������������������������������������������������������� 103 Choosing from Different Event Types���������������������������������������������������������������������������������������� 105 Creating Events������������������������������������������������������������������������������������������������������������������������� 106 Understanding the Changes������������������������������������������������������������������������������������������������ 108 Modifying Event Handlers��������������������������������������������������������������������������������������������������������� 109 Exploring the Changes in Detail������������������������������������������������������������������������������������������� 113 Creating Events in Components������������������������������������������������������������������������������������������������ 114 Forwarding Events�������������������������������������������������������������������������������������������������������������������� 114 Breaking Apart the Changes������������������������������������������������������������������������������������������������ 116 A Point of Note��������������������������������������������������������������������������������������������������������������������� 117

vii

Table of Contents

Life Cycling Events in Svelte����������������������������������������������������������������������������������������������������� 118 Working with onMount�������������������������������������������������������������������������������������������������������� 119 Exploring beforeUpdate������������������������������������������������������������������������������������������������������� 122 Understanding How It Works����������������������������������������������������������������������������������������������� 123 Implementing Actions��������������������������������������������������������������������������������������������������������������� 124 Reworking the Code������������������������������������������������������������������������������������������������������������ 126 Understanding What Happened������������������������������������������������������������������������������������������� 127 Adding Functionality to Our Site����������������������������������������������������������������������������������������������� 128 Adding a Modal������������������������������������������������������������������������������������������������������������������������� 129 Exploring Changes Made to Code���������������������������������������������������������������������������������������� 131 Exploring the Examples������������������������������������������������������������������������������������������������������� 131 Using the Plugin – An Epilogue�������������������������������������������������������������������������������������������� 132 Summary���������������������������������������������������������������������������������������������������������������������������������� 133

Chapter 6: Binding Elements�������������������������������������������������������������������������������� 135 Creating Forms in Svelte����������������������������������������������������������������������������������������������������������� 135 Catering for Different Form Elements��������������������������������������������������������������������������������������� 136 Working with Numeric Inputs���������������������������������������������������������������������������������������������� 136 Using Checkbox Inputs�������������������������������������������������������������������������������������������������������� 138 Handling Multiline Text Area Inputs������������������������������������������������������������������������������������� 138 Selecting Choices���������������������������������������������������������������������������������������������������������������� 139 Dealing with Content Editable Fields����������������������������������������������������������������������������������� 139 Binding and Managing Other Events����������������������������������������������������������������������������������� 140 Building a Composite Example������������������������������������������������������������������������������������������������� 141 Breaking the Code Apart������������������������������������������������������������������������������������������������������ 145 Managing Context��������������������������������������������������������������������������������������������������������������������� 146 Understanding the Changes������������������������������������������������������������������������������������������������ 150 Adding a Contact Form to Our Demo���������������������������������������������������������������������������������������� 150 Introducing Svelte-Yup�������������������������������������������������������������������������������������������������������� 151 Laying the Groundwork������������������������������������������������������������������������������������������������������� 152 Building the Contact Form��������������������������������������������������������������������������������������������������� 153 Summary���������������������������������������������������������������������������������������������������������������������������������� 158 viii

Table of Contents

Chapter 7: Adding Styles�������������������������������������������������������������������������������������� 159 Making Some Small Adjustments��������������������������������������������������������������������������������������������� 159 Understanding Styling in Svelte������������������������������������������������������������������������������������������������ 161 Adding Styling to the Front-End Demo�������������������������������������������������������������������������������������� 161 Updating the Global Stylesheet������������������������������������������������������������������������������������������� 162 Styling the Pages����������������������������������������������������������������������������������������������������������������� 164 Styling the Header and Footer��������������������������������������������������������������������������������������������� 167 Styling the Buttons�������������������������������������������������������������������������������������������������������������� 168 Styling the Product Pages and Cart������������������������������������������������������������������������������������� 169 Using a Style Preprocessor������������������������������������������������������������������������������������������������������� 173 Breaking the Code Apart������������������������������������������������������������������������������������������������������ 176 Taking Things Further��������������������������������������������������������������������������������������������������������������� 177 Summary���������������������������������������������������������������������������������������������������������������������������������� 179

Chapter 8: Unit Testing and Svelte������������������������������������������������������������������������ 181 Deciding Our Strategy��������������������������������������������������������������������������������������������������������������� 181 Browser Support����������������������������������������������������������������������������������������������������������������������� 183 Setting Up the Test Environment����������������������������������������������������������������������������������������������� 183 Understanding the Changes Made�������������������������������������������������������������������������������������� 186 Creating an Example Test���������������������������������������������������������������������������������������������������������� 187 A Note About File Structure������������������������������������������������������������������������������������������������������� 190 Applying Principles to Our Project�������������������������������������������������������������������������������������������� 190 Writing Tests for the Home Page����������������������������������������������������������������������������������������� 191 Testing the Remaining Content Pages��������������������������������������������������������������������������������� 195 Testing the Product Pages and Cart������������������������������������������������������������������������������������ 199 Debugging Svelte���������������������������������������������������������������������������������������������������������������������� 204 Using Lighthouse���������������������������������������������������������������������������������������������������������������������� 207 Summary���������������������������������������������������������������������������������������������������������������������������������� 209

Chapter 9: Deploying Svelte��������������������������������������������������������������������������������� 211 Doing Final Checks������������������������������������������������������������������������������������������������������������������� 211 Understanding the Deployment Process����������������������������������������������������������������������������������� 214 ix

Table of Contents

Setting Up the Hosting Provider������������������������������������������������������������������������������������������������ 215 Checking the Default Branch���������������������������������������������������������������������������������������������������� 218 Deploying Content to Production���������������������������������������������������������������������������������������������� 219 Breaking Apart the Changes������������������������������������������������������������������������������������������������ 222 Adding a Custom Domain Name����������������������������������������������������������������������������������������������� 222 Breaking Apart the Code Changes��������������������������������������������������������������������������������������� 226 Taking It Further������������������������������������������������������������������������������������������������������������������������ 227 Summary���������������������������������������������������������������������������������������������������������������������������������� 231

Chapter 10: Working with External Libraries������������������������������������������������������� 233 Importing Libraries into Svelte�������������������������������������������������������������������������������������������������� 233 Testing Compatibility with Svelte���������������������������������������������������������������������������������������������� 235 Exploring the Code in Detail������������������������������������������������������������������������������������������������ 240 Working Client Side vs. Server Side������������������������������������������������������������������������������������������ 241 Why Is Svelte Different?������������������������������������������������������������������������������������������������������ 242 Adding a Payment Processor���������������������������������������������������������������������������������������������������� 242 Getting Prepared����������������������������������������������������������������������������������������������������������������������� 243 Taking a First Look at the PayPal Demo������������������������������������������������������������������������������ 245 Adding PayPal to Our Front-End Site���������������������������������������������������������������������������������������� 247 Testing the Result���������������������������������������������������������������������������������������������������������������� 251 Reviewing the Changes Made��������������������������������������������������������������������������������������������� 254 What About React?�������������������������������������������������������������������������������������������������������������������� 255 Breaking Apart the Changes������������������������������������������������������������������������������������������������ 258 Summary���������������������������������������������������������������������������������������������������������������������������������� 258

Chapter 11: Animating Svelte������������������������������������������������������������������������������� 261 Auditing the Site����������������������������������������������������������������������������������������������������������������������� 261 Learning a Language���������������������������������������������������������������������������������������������������������������� 262 Understanding How the Code Works����������������������������������������������������������������������������������� 267 Reviewing the Types of Animation Options������������������������������������������������������������������������������� 268

x

Table of Contents

Applying Easing Effects������������������������������������������������������������������������������������������������������������ 269 Creating Custom Easing Effects in JavaScript�������������������������������������������������������������������� 269 Using Styles to Create Custom Easing Effects�������������������������������������������������������������������� 272 Taking It Further������������������������������������������������������������������������������������������������������������������ 274 Using Svelte Libraries��������������������������������������������������������������������������������������������������������������� 275 Applying Animation to Our Project�������������������������������������������������������������������������������������������� 276 Adding Animation to the Banner������������������������������������������������������������������������������������������ 277 Updating the Cart Action������������������������������������������������������������������������������������������������������ 278 Iterating Through Pictures��������������������������������������������������������������������������������������������������� 282 Summary���������������������������������������������������������������������������������������������������������������������������������� 285

Chapter 12: Adapting for Sapper�������������������������������������������������������������������������� 287 Introducing... Sapper?��������������������������������������������������������������������������������������������������������������� 287 Migrating Our Project – Setting Expectations��������������������������������������������������������������������������� 288 Setting Up the Initial Site���������������������������������������������������������������������������������������������������������� 289 Exploring the Code in Detail������������������������������������������������������������������������������������������������ 291 Understanding the Structure of a SvelteKit Site����������������������������������������������������������������������� 292 Updating the Layout������������������������������������������������������������������������������������������������������������ 293 Adding Pages����������������������������������������������������������������������������������������������������������������������� 296 Adding Product Gallery�������������������������������������������������������������������������������������������������������� 297 Adding Product Page����������������������������������������������������������������������������������������������������������� 300 Migrating Styles������������������������������������������������������������������������������������������������������������������ 303 Breaking Apart the Code������������������������������������������������������������������������������������������������������ 306 Testing the Site and Next Steps������������������������������������������������������������������������������������������������ 307 Summary���������������������������������������������������������������������������������������������������������������������������������� 309

Appendix: Getting Help����������������������������������������������������������������������������������������� 311 Index��������������������������������������������������������������������������������������������������������������������� 313

xi

About the Author Alex Libby is a front-end engineer and seasoned computer book author who hails from England. His passion for all things open source dates back to the days of his degree studies, where he first came across web development and has been hooked ever since. His daily work involves extensive use of React, Node.js, JavaScript, HTML, and CSS. Alex enjoys tinkering with different open source libraries to see how they work. He has spent a stint maintaining the jQuery Tools library and enjoys writing about open source technologies, principally for front-end UI development.

xiii

About the Technical Reviewer Rami Morrar is a self-taught programmer and has coding experience in languages such as C# and C++ for over three years. He has made different coding projects, such as a gaming tutorial website, several desktop applications, and even games in the Unity game engine. He is currently working on his own independent game project in MonoGame, set to be released next year. He has an abundance of charisma for programming and game development, and talks about both on his blog, and tutorials he has created for the MonoGame framework. He is also cowriting a sequel to the book MonoGame Mastery. In his free time, he likes to play games and look at cool new projects by other indie developers.

xv

Acknowledgments Writing a book can be a long but rewarding process; it is not possible to complete it without the help of other people. I would like to offer a huge vote of thanks to my editors – in particular, Nancy Chen and Louise Corrigan; my thanks also to Rami Morrar as my technical reviewer, James Markham for his help during the process, and others at Apress for getting this book into print. All have made writing this book a painless and enjoyable process, even with the edits! My thanks also to my family for being understanding and supporting me while writing. I frequently spend lots of late nights writing alone, or pass up times when I should be with them, so their words of encouragement and support have been a real help in getting past those bumps in the road and producing the finished book that you now hold in your hands. Lastly, it is particularly poignant that the book was written at a time when the world has faced global events of an unprecedented nature; it was too easy to think about those who lost the greatest thing we as humans could ever have. Having a project to work on – no matter how simple or complex it might be – helped me get through those tough times, and with the hope that we face a new, improved, and hopefully better future.

xvii

Introduction Practical Svelte is for people who want to quickly create ecommerce sites that are efficient and fast, using the upcoming Svelte framework and associated tools. This project-oriented book simplifies the setting up of a Svelte site as a starting point before beginning to explore the benefits of using Svelte in an ecommerce environment and developing it into an ecommerce offer that we can customize according to your needs. It will equip you with a starting toolset that you can use to create future projects, incorporate into your existing workflow, and that will allow you to take your websites to the next level. Throughout this book, I'll take you on a journey through constructing the front-­ end UI for our example site. We will touch on subjects such as adding data sources, creating the catalog, and implementing a payment function and more – showing you how easy it is to develop simple ecommerce sites that we can augment later quickly. With the minimum of fuss and plenty of practical exercises, we'll focus on topics such as managing data and state, styling, creating components, and more – right through to producing the final result viewable from any browser! Svelte uses nothing more than standard JavaScript, CSS, and HTML, three of the most powerful tools available for developers: you can enhance, extend, and configure your site as requirements dictate. With Svelte, the art of possible is only limited by the extent of your imagination and the power of JavaScript, HTML, and Node.js. Practical Svelte gets you quickly acquainted with creating and manipulating ecommerce sites using tools familiar to all developers. It's perfect for website developers who are already familiar with JavaScript and are keen to learn how to leverage the Svelte framework. You may also be a developer for whom time is of the essence and simplicity is key; you need to produce efficient and properly optimized content in modern browsers using tools already in your possession.

xix

CHAPTER 1

Getting Started Wait, this new framework has a runtime? Ugh. Thanks, I’ll pass. Let me begin with a single fact: we’re shipping too much code to our users. Yes, it might well be the case that tools, such as React and Angular, are all the rage nowadays. But most of them have one thing in common – they each have a runtime library that must run when rendering websites using these tools. Sure, this might be a necessary evil when creating component-driven websites, but it’s okay, as everyone does it, right? It’s not okay. We may think it’s acceptable to run a 100Kb+ runtime with the likes of React, but it’s not just the code we’re using. We have to consider the bandwidth, server resources, external resources (such as third-party libraries or assets), and so on – it starts to add up! Can we do anything about this? We can, by answering this question: What if our framework didn't run in the browser?

I ntroducing Svelte Asking this question might seem like a real shocker when we’ve been used to the likes of React, but it is possible – let me introduce you to Svelte! Created by Rich Harris in 2016, it was designed to prove that you don’t need to create lots of extra component code but could write code that is much closer to vanilla JavaScript. Following this mantra means you can reduce the amount of code you need overall; in a sense, Svelte follows the principle of not reinventing the wheel when you already have perfectly good markup that can do the job. However, what makes it work is that it compiles code into reusable JavaScript modules – without the need to operate the framework at runtime.

© Alex Libby 2022 A. Libby, Practical Svelte, https://doi.org/10.1007/978-1-4842-7374-6_1

1

Chapter 1

Getting Started

Not running a framework at runtime is significant: we don’t pay the cost of shipping a sizable runtime library (and yes, tools like React get bigger, not smaller), plus our application will be super fast, without the abstraction you otherwise get with other tools. Throughout this book, I will take you on a journey through creating a simple frontend ecommerce store that we can use on any small to medium online retail site. We’ll start with a quick review of how Svelte works in this chapter but then swiftly move through creating the various components required for our store, as well as sourcing data. We’ll take a look at a host of different topics on the way, such as managing events, styling, and the like – with the focus on creating our store but learning about the various parts that make up Svelte. We have a lot to cover – so without further ado, let’s dive in. As with all things programming, we will be setting up our development environment, ready for working on our Svelte project.

Setting Up a Development Environment Okay, with the introductions over, it’s time to get to business! Throughout this book, we will be building up a sample ecommerce storefront, which we can later attach to a back-end payment system such as Shopify. We, of course, need Svelte (after all, that is what this book is about!), but we also need to avail ourselves of a few tools, so without further ado, here is a list of what we need:

2



A copy of Svelte – there are two ways to get it; we will explore this shortly.



A text editor, such as Atom or Visual Studio Code – I would recommend taking a look at https://svelte.dev/blog/settingup-your-editor, which details ways to set up some of the more popular editors for use with Svelte.



We also need Node.js – not only for Svelte but also for other tools such as webpack. Go ahead and download a version suitable for your platform from www.nodejs.org – choosing the default settings will be sufficient for this book.



A local web server such as Apache (www.apachefriends.org) – for Linux users, you may find this already available in your distro. For this, default settings will suffice; it’s not necessary to add SSL support.

Chapter 1

Getting Started



A hosting account from a service such as Vercel, Surge, or Now for publishing our site.



A Git account, with either GitLab or GitHub. I usually use GitHub (as I already have lots of GitHub repositories); please feel free to adapt for GitLab if preferred.



An optional extra is a custom domain name – this isn’t obligatory, but it will give our demo a little extra polish!

If you happen to use the Prettier tool in your browser, then I would strongly recommend checking out www.rockyourcode.com/prettier-and-es-lintsetup-for-svelte-js/ and in particular for details on setting up Prettier to work with Svelte. The Svelte plugin for Prettier is available at https://github. com/sveltejs/prettier-plugin-svelte. We need a couple of things later in the book, but we will go through details nearer the time. We can download any other Node.js packages as and when needed; I will highlight this at the appropriate point. Okay, let’s move on. I’ve touched on the fact that we need Svelte, but asked one question: how do we get a hold of and install it? There are a couple of options open to us, so let’s take a look at them in greater detail.

So How Do We Get Svelte? One of the great things about Svelte is that as a JavaScript-based framework, it is straightforward to set it up – there are several options open to us: 1. Use the REPL at https://svelte.dev/repl/hello-world? version=3.31.2 to familiarize ourselves with Svelte – this has several examples at https://svelte.dev/examples, which we can tweak to suit our needs.

The example URL will redirect to show the first in the list; you can use that list to select an appropriate option. 3

Chapter 1

Getting Started

2. When we outgrow the REPL option, we can download and install a customized version from the Svelte GitHub site, using Node.js/ NPM. 3. We can also use degit, a project scaffolding tool available from https://github.com/Rich-Harris/degit, to set up a new Svelte project. Using this route would typically require entering these commands: npx degit sveltejs/template my-svelte-project cd my-svelte-project npm install npm run dev 4. If you’re something of a traditionalist like me, you can also install directly using NPM too – this is perfectly fine.

We will cover Svelte installation in more detail later when we set up our base site for this book. By default, Svelte comes with the Rollup tool to manage the bundling of ES modules; we can swap it out for different integrations, depending on what tools we already use. For example, you might choose to work with webpack instead – Svelte has a plugin available at https://github.com/sveltejs/svelte-loader to support this system. Alternatively, you can use the sirv-cli tool to preview assets directly – this is available from https://github.com/lukeed/sirv.

All of the demos in this book were written for Windows, as this is the author’s usual development platform. Please adapt if you are using macOS or Linux on your PC. Now that we have our development environment set up, let’s try creating Svelte code using the REPL tool.

4

Chapter 1

Getting Started

Creating Your First Application We could spend ages talking through how Svelte works, but that’s not so interesting – instead, let’s dive in and use the REPL tool to start manipulating some simple Svelte code! It’s a great way to learn, mainly as Svelte code is structured in a format that closely resembles how you might write a CodePen demo. We will revisit this structure shortly in more detail, but for now, let’s dive in and take a quick look at a typical “Hello World” app to get up to speed with using Svelte.

BREAKING INTO USING REPL To get acquainted with Svelte, using the REPL tool, follow these steps: 1. First, crack open your browser and navigate to www.svelte.dev. Click the REPL link at the top right of the page.

The keen-eyed among you will note that you could equally browse directly to the REPL tool once you know the link. Browsing to this URL will work, but be aware though that it includes a version-specific reference to Svelte. You may end up invertedly browsing to and using an older version of Svelte if you’re not careful! 2. Once at the page, you will see a split code window – on the left is an open file, App.svelte, with the Result, JS output, and CSS output tabs on the right. The tool comes with a version of the typical “Hello World” app running, which we can see in Figure 1-1.

5

Chapter 1

Getting Started

Figure 1-1.  A screenshot of the REPL tool for Svelte 3. Try changing the value assigned to the name from 'world' to your name – see how it changes automatically on the right? 4. Let’s add a little color to the result – after the opening Hello {name}!

5. The results shown on the right will automatically update, so we end up with “Hello…” in a purple font.

6

Chapter 1

Getting Started

6. Okay, let’s ramp things up a little. Inside the script block, leave a blank line after the let name= entry, and add this:

7. Next, add in this button code immediately after the tag: Hello {name}!

  Click me

8. Try clicking the “Click me” button – what do you get? If all is well, we should see a dialog appear (Figure 1-2, shown overleaf).

Figure 1-2.  Clicking the button shows our first dialog box

7

Chapter 1

Getting Started

You’ve now completed your first Svelte demo – easy, right? Most of the code we’ve used is plain vanilla JavaScript, but with some key differences: let’s take a moment to review what we’ve covered in this demo in more detail.

Understanding What Happened So, what did we achieve in that last demo? It is fair to say that while it may seem to have been a trivial exercise, this was intentional – it was more about working through the constituent parts of a typical Svelte application than exploring the intricacies of the code itself! We will explore the code in more detail throughout this book, but for now, let’s take a quick look at the sections that make up our application. As a quick recap, here is the code we’ve just used in full:

Hello {name}!

  Click me

You will see it’s made up of three parts – we’ve included a

We’ve used basic styling here, but Svelte can use external style libraries such as emotion as well – we will cover how in Chapter 7. Finally, we have package.json, which is standard for all Node.js-based applications – inside it, you can see the packages that have already been installed and configured for use: {   "name": "svelte-app",   "version": "1.0.0",

17

Chapter 1

Getting Started

  "scripts": {     "build": "rollup -c",     "dev": "rollup -c -w",     "start": "sirv public"   },   "devDependencies": {     "@rollup/plugin-commonjs": "^17.0.0",     "@rollup/plugin-node-resolve": "^11.0.0",     "rollup": "^2.3.4",     "rollup-plugin-css-only": "^3.1.0",     "rollup-plugin-livereload": "^2.0.0",     "rollup-plugin-svelte": "^7.0.0",     "rollup-plugin-terser": "^7.0.0",     "svelte": "^3.0.0"   },   "dependencies": {     "sirv-cli": "^1.0.0"   } } The files we’ve run through are core to making Svelte work – we will, of course, add more when we develop components, but they will hang off these initial files. Okay, let’s crack on. I’ve hinted that we will be building an online store front end as the theme for this book. The question is, what will our store sell, I wonder?

Setting the Background Coffee time! Coffee, coffee, coffee, coffee…! Yes, indeed, our store will be selling coffee! At this point, I’m reminded of that saying from the movie Dante's Peak, where Greg, one of the geologists studying a volcano about to cause havoc with the town Dante’s Peak, goes a little crazy when given his daily cup by the town’s mayor and coffee shop owner. But I digress… For this book, we will build out an online store that will sell roast coffee beans. Billed as one of the world's most popular drinks, coffee consumption is increasing, with America, Germany, Italy, and Japan being among the biggest importers of the product. 18

Chapter 1

Getting Started

Throughout this book, we will explore the different elements that make Svelte, such as creating components, managing state, and adding data. We’ll also cover the logic required to route information, responding to events, and more – all will be based on creating code for our store, but at the same time, I will cover the essential theory for each topic. We will then finish deploying our project to a host and exploring what we can do to extend it further by adding in payment facilities. So, as you can see, we have plenty to cover!

Summary We can see creating a website as something of a roller coaster – there will be highs and lows, successes, and challenges to deal with, as we begin to develop what will become our final solution. Over these last few pages, we’ve started to look at our project’s background and get ourselves ready to create the site – let’s take a moment to review what we have learned before beginning the real development work. We started by introducing Svelte before swiftly moving onto set up our development environment and exploring the various options to obtain the framework. We then dipped our toes into our first application, using the REPL playground, before exploring some of the principles behind how Svelte works and what makes it different from other frameworks. We then rounded out the chapter by setting up the base site for our project. At the same time, we also covered the background details of what we will develop in this book. Okay, so what’s next? Ah, yes, we need to start creating components that will form the basis of our online store! There is a good handful to make, so stay with me, and I will reveal all in the next chapter.

19

CHAPTER 2

Creating Components Okay, so we have our tools in place and installed our prerequisites. Let’s crack on and build that shop! First, I want to cover off some of the basics principles around creating components in Svelte. As I am sure you will already be aware, dozens of frameworks have appeared on the scene like React, Vue, and Angular as examples. With so many appearing, it’s almost impossible to have not heard of at least one. Question though: What do these frameworks have in common? The answer is that they are component driven; Svelte is no different. This component-based architecture allows us to separate features into individual pieces of reusable functionality and make it easier to develop and debug our code. In this chapter, we will work through the basics of creating components in Svelte. We will use our new-found knowledge to build components for our mini shopping cart that we talked about back in Chapter 1. Let us begin building our first ever component in Svelte.

Understanding the Makeup of Components If you have ever used CodePen demos, then you already know the basics behind creating Svelte components! But I digress. Getting back to reality, though, it doesn’t matter which framework those demos used – it might have been Vue, React, or even plain vanilla JavaScript. The same thing applies in each instance: CodePen demos are (broadly) separated into three areas, namely, CSS, HTML, and JS (or JavaScript). We can include links to external libraries, but the same principle still applies: our core code will reside in one of these areas.

© Alex Libby 2022 A. Libby, Practical Svelte, https://doi.org/10.1007/978-1-4842-7374-6_2

21

Chapter 2

Creating Components

Svelte works on precisely the same principle – we split code into three areas, each contained within their relevant markup tags. To see what I mean, let’s go ahead and create some examples, so you can see how this works in practice.

Creating an Example Component The best way to get started with creating a Svelte component is to use the REPL tool. Although this might sound a little odd as a name, it is just a playground for writing code; it works in the same way as CodePen demos, so you should have no difficulty using it! We can use the browser version, which is available at https://svelte.dev/repl, which is perfectly fine for our needs.

The URL for the Svelte REPL playground will redirect to a version-specific URL – this is normal and expected. I you run the URL in Chrome, you can install the playground as an app in your browser – click the link highlighted in Figure 2-1 to install the app when prompted.

Figure 2-1.  The REPL playground in a browser Wait for it to show this window (Figure 2-2).

22

Chapter 2

Creating Components

Figure 2-2.  The same REPL playground as an installed app We can then use the download symbol (second from left in the blue-gray bar) to download the finished code or create an account to save our work online if desired. Okay, assuming you’ve added the app (or are on the REPL playground in the browser), let’s start creating our demo component as part of the next exercise.

Building the Example Component To start our foray into creating components in Svelte, we will warm up with a quick demo by creating a Button component – this may be very simple, but it shows off some key features of creating and importing components in Svelte. Let’s take a look at how it works in more detail.

CREATING A CUSTOM BUTTON To set up the Button component, go ahead and follow these steps: 1. First, fire up your browser, and head over to https://svelte.dev/repl; the URL will redirect to show a version-specific address – this is normal.

23

Chapter 2

Creating Components

2. Next, in the tab marked App.svelte on the left, add this code:

3. Next, click the plus symbol to the right of the word App.svelte to add a new component. 4. When prompted (it will show Component2.svelte), change the name to DefaultButton.svelte. 5. Go ahead and add in this script code to that tab:

6. In the same tab, miss a line and then add in this style block:

7. Finally, leave a line blank, and then add in this markup:

  Hello World

24

Chapter 2

Creating Components

8. The editor will automatically save the code – after a few moments, you will see the button shown in Figure 2-3.

Figure 2-3.  The finished button displayed in the REPL playground 9. Go ahead and click it – you will see the message appear as indicated in Figure 2-4.

Figure 2-4.  The message displayed from our button 10. The demo is now complete – you can either download the code for future use or save it if you have logged in with an account. Congratulations, you’ve now created your first component in Svelte! I know that some of you might wonder what all the fuss is about, as that was a straightforward exercise. But his simplicity is what makes Svelte so fantastic; it was designed to require minimal code and operate very much like writing CodePen-style demos. However, it hides a lot of the code required to create and run the demo; if you look at the JS output window in the REPL playground, you will see what I mean! Our less than 24 lines are multiplied by a factor of almost 5 when it comes to building the final code! But I digress. Although the code looks very straightforward, it does include a couple of essential points that are worth noting – let’s take a look at the code in more detail.

25

Chapter 2

Creating Components

Reviewing the Code So, what did we achieve in the last demo? If we take a closer look at the code again, we can see that much of what we wrote was plain HTML markup and CSS styling – this in the main is just standard code, so easy to understand. However, what makes it different is the simple, easy-to-read style of coding – Svelte uses the same principles used by CodePen, where we focus on the key elements and let Svelte build the code into valid JavaScript. In this last demo, we created a simple Button component – we started in App.svelte by adding an import to our base component before calling an instance of it on the page. We then switched to creating that component; at the top of DefaultButton.svelte, we first inserted a script block that contains an export statement:

In a nutshell, export in Svelte allows us to expose a property from within a component, which we can call from a parent component. In this case, we exposed buttonAction, which triggers the alert to display the message. Next up came a styling block, using standard CSS styles available to any component that supports them. We then moved onto the last block, which is the markup:

  Hello World

At face value, this looks like any other standard markup for a element, but notice the presence of ? It is a placeholder for any child elements that should reside inside the parent button element, which will override any text or elements present in the original component. That last statement is crucial – if we were using React, for example, then we would have done something like this:

26

Chapter 2

Creating Components

“There is nothing wrong with using prop values, right?” I hear you say we override what’s already in the component, right? I would 100% agree with you: but what if we didn’t have to specify that prop value? Svelte is clever enough to work out if there are any child elements and drop them into the placeholder – no need to specify a prop value! To prove it, change the tag to this in your demo:

    This is an overridden button

Watch how it changes automatically in the Result window on the right (Figure 2-5). See how easy that was to change the text?

Figure 2-5.  The updated button in the REPL demo Okay, now that we’ve become acquainted with the basics of using components, let’s put some of that knowledge to good use and begin to create the first components for our shopping cart demo. Over the following few pages, we’ll reuse some of these principles to build out components to make a simple cart icon at the end of the chapter, which we will then style later in the book.

S  etting Expectations At this point, it’s an excellent time to set some expectations – after all, we simply don’t have the space to build something that replicates the likes of Amazon!

27

Chapter 2

Creating Components

It’s important nonetheless to set a few boundaries, so with that in mind, here they are: •

The site we will create won’t be production-ready by any stretch of the imagination: we would need to add security, a lot more error checking, and scale it up to handle a lot more products!



We will focus on using Svelte to provide a front end to our site. Svelte can work with tools such as GraphQL for managing data, but support is not enabled by default; we would have to use a third-party plugin for this purpose. To keep things simple, we will define a small JSON-­ based data block; in an ideal world, we would scale up to the likes of GraphQL to better manage expected volumes.

We will explore what would be required to hook into GraphQL later in Chapter 3. •

We can use Svelte with tools such as GraphQL or routers, but it’s important to remember that Svelte doesn’t operate in the same way as React or Angular, which comes with many of these tools built-in as standard.



The demo we will build will act as a sound basis for developing your projects – there will be features that we won’t include in this demo, but we would need to later. I will go through some suggestions later in the book.

Okay, let’s continue. Before we start coding, let’s quickly cover an essential part, which is understanding the architecture we will use in our demo.

Working Out the Architecture Architecture is an essential part of any site – this is what makes it easier to manage features such as data or state and help keep our code DRY, so we’re not repeating ourselves too often. For this book, we will keep the structure very simple, with all of the various elements we create in the \src folder. If we take a look at the folder structure, we can see that the \src folder contains the files and folders listed in Figure 2-6 – note that App.svelte and main.js come as standard; we will create the others. 28

Chapter 2

Creating Components

Figure 2-6.  The list of components for our project Inside the \components folder, we will create the following: •

Button.svelte – We’ll use this for the add-to-cart feature in the product gallery and on individual product pages.



Cart.svelte – This is the main shopping cart component for the site.



Header.svelte and Footer.svelte – These we will use to create the header and footer for the page layout.



Products.svelte – This forms the main product gallery for the site.



Product.svelte – This is the product card with individual details of a chosen product.

Switching to the \pages folder, we will add three pages: About, Coffee, and Home. These are not compulsory, but give a little context to the site and make it look a little more realistic. The About and Home pages will be self-explanatory; the Coffee page is a little history about the coffee we would be selling from our site.

There are two ancillary files we will also create and store at the root of the \src folder in the next chapter – these are productlisting.js and stores.js.

29

Chapter 2

Creating Components

To understand how it all hangs together, let’s take a look at a schematic of the site architecture that I’ve created in Figure 2-7.

Figure 2-7.  Architectural schematic of the site Here, we can see the parent App.svelte, which calls components and pages from the src folder. During the build process, Svelte pulls the script code into a compiled ­bundle.js file, with styles in bundle.css. We can directly call images from within the \public\images folder, at the same time. As you’ve been working through the demo, notice anything particular about filenames, say in comparison to React? It doesn’t matter if we’re developing a page or component; they are effectively the same thing when it comes to file naming in Svelte. It comes with a big proviso, though: they all follow the same structure, but when it comes to adding code, there are some differences.

We will cover it later in more detail. Moving on, the first task is to update the main application component, App.svelte.

30

Chapter 2

Creating Components

Making a Start with App.svelte For our first exercise, we need to update the App.svelte file – this is effectively the master file, of which all of the other files will hang. We’ll use this to generate the structure for our page – let’s take a look at what is involved in more detail.

CREATING APP.SVELTE To update the App.svelte file, follow these steps: 1. We’ll start by opening a copy of App.svelte – delete the line of code between the

2. Next, leave a line blank, and then add in this block – this will take care of managing the navigation for the site:

       Home     Shop     Our Story     Our Coffee   

31

Chapter 2

Creating Components

3. Although we’ve added in navigation, it won’t work immediately – it’s reliant on setting up a plugin, which we will cover momentarily. For now, go ahead and remove the markup between the existing tags, and then replace it with this:        

4. We’re almost there – to close off the markup, we need to add in the closing tag for , followed by the call to what will be our footer:

5. Next, leave a line blank, and then add in this block – this is a placeholder for styles that we will add in a later chapter:

6. Go ahead and save the file and close it – we have finished with the file for now. 7. Now fire up a Node.js terminal session and change the working folder to our project area. 8. At the prompt, run this command to install our missing plugin: npm install svelte-routing -s

9. We’ve completed the changes – if we were to run npm run dev to fire up the Svelte dev server and preview the changes, we wouldn’t get anything! It will result in our code generating several errors; this is to be expected. Don’t worry, though – we will fix most (if not all) of them in this chapter!

32

Chapter 2

Creating Components

We now have the basics for our site, but I’ll bet you’re wondering: what exactly have we added? It is what makes Svelte so easy to use; we focus on producing clean, easy-to-­read code! Most of what we add will be standard JavaScript, CSS, and HTML markup, with only a few Svelte keywords in the mix. That said, we should cover a couple of essential points from this demo, so let’s take a moment to review the code in more detail.

Reviewing the Code Changes So, what did we create? Well, we can consider App.svelte as the root component for our site; all other components hang off this one. To set ours up, we kicked off by including a handful of imports. Most of these are for pages, such as About, Coffee, and Home, but we also import the svelte-routing plugin and stores.js file simultaneously. We will cover the significance of stores.js later in the book, but for now, let’s explore what this svelte-routing plugin does in more detail. To understand how it works, move down to the line of code at the start of our markup. This line is where our navigation starts; Svelte takes each page we want to display and displays it as a module within the parent page, App.svelte. So, if we were to navigate to Shop Shop Svelte-routing uses the Route line a little lower to display the Products.svelte component on the page:

Sounds straightforward enough, right? Well, svelte-routing can achieve a lot more; imagine if we needed to navigate to a dynamic link such as in a blog: Blog In this case, svelte-routing would take the ID of the post link and use it to route to the blog page, using a link such as this:

33

Chapter 2

Creating Components

I would strongly recommend looking at the GitHub site documentation for this plugin at https://github.com/EmilTholin/svelte-­routing. We’ve only touched the surface of what is possible with this plugin! Moving on, with the main App.svelte file in place, we can start to build out the components needed for our mini site. We could link to them individually, but a better method is to build a component index – to see why, let’s take a peek at the code in more detail.

Setting Up the Component Index Now we need to set up a component index! I suspect those of you who have used tools, such as React or Vue, will be familiar with this principle. For the uninitiated, we create a file that contains references to each of the components we use. How is this of use to us? Well, take another look at the top of the app.svelte file we’ve just created – notice this statement?

2. Next, leave a line blank, and add in this placeholder – this is something we will update later in Chapter 7:

3. Finally, we also need to add in our markup – for this, go ahead and leave an empty line, and then add in this code:

       Small Coffee Company           {$counter}   

4. Extract a copy of the images folder from the code download that accompanies this book, and save it to the \src\public\ folder – this will provide images for the various components and pages for our mini site, including the header. 5. Save the file as header.svelte in a new folder called components, under the \src folder – we can close it.

36

Chapter 2

Creating Components

Short, sweet, and straightforward – that’s how I like my exercises. Okay, yes, I know that might open me up to various – shall we say – comments, but there is some truth in the matter: anything for a simple life! There is, however, one crucial point that we should explore more from this demo – the use of the writable import. Ordinarily, I would go into detail here, but we will cover it and more when we explore data and state management in the next chapter. For now, all we need to know is that it deals with passing values between components and that this (in a way) is similar to the principles used by React’s props facility. Let’s move on. The next component we will set up is the footer – this one is purely markup, although we use a plugin. To see what I mean, let’s dive in and take a look.

Setting Up the Footer We have the main app file in place, along with our component index and the header – we can’t have the latter without top and tailing it with a footer! Fortunately, this is just as easy to set up – let’s take a look at what’s involved in more detail.

BUILDING THE FOOTER To get the footer set up and ready for use, work through these steps: 1. First, fire up a new file in your editor – go ahead and save it as Header. svelte in the \src\components folder. 2. Next, go ahead and create a new folder inside our project area – call it public. 3. Extract a copy of the images folder from the code download that accompanies this book, and drop the entire folder into the \public folder. 4. Next, go ahead and add in this script block at the top of the file – this will take care of handling some SVGs that we use in the footer:

5. As before, we need to add in a placeholder for some styling that will come later – for this, leave a blank line, and then add in this block:

6. The remaining code is markup that forms our footer – go ahead and add the following below the style block, leaving a blank line before it:

       &​copy; Small Coffee Shop 2021                                        

7. Save the file – you can now close it. That’s another step closer to getting the basic site set up – we still have a few more components to add, though! Most of what we added in this demo is just plain HTML markup; the CSS styling we will add later when we cover styling in Chapter 7. There is one point of interest, and that’s the plugin we’ve used: svelte-inline-svg. 38

Chapter 2

Creating Components

The plugin is available from https://github.com/robinscholz/svelte-­inline-svg; it does as it says on the tin by inlining SVG images into our markup. We inserted three SVGs using code similar to this:

  

The plugin turns that code into this (Figure 2-8).

Figure 2-8.  Example of inline SVG code using the InlineSVG plugin It is preferable to in-line SVGs where possible, as we can style individual elements within the SVG. SVGs in image files will be treated as images and can only be styled via externally facing properties such as width and height. Okay, let’s keep going and turn our attention to setting up the product gallery, which will be the shop window to our store.

Creating the Product Gallery Assembling the product gallery is the most critical part of our project – after all, we clearly wouldn’t be able to sell without products and therefore make money! For this book, we’ll keep to just a handful of products that we will source from a data block – we will explore sourcing data using other methods later in the book. To get things started, let’s take a look at the code required in more detail.

39

Chapter 2

Creating Components

CONSTRUCTING THE PRODUCT GALLERY To get the product gallery wired up, follow these steps: 1. We’ll start by cracking open a new file, saving it as products.svelte, at the root of the \src\components folder. 2. Next, go ahead and add this script block – this will take care of adding products to our basket directly from the product gallery:

3. Go ahead and miss a line, and then add in this placeholder – we will come back to adding styles later in this book:

40

Chapter 2

Creating Components

4. Finally, we need to add in the markup that will render the products on the page – for this, go ahead and add in this code, leaving a line blank first after the style placeholder:

  {#each $products as product}                 {product.name}     

${product.price}

     addToCart(product)}>Add to cart        {/each}

5. Go ahead and save the file, and then close it. Although we are getting close to a starting site that runs, if we were to run our code now, it would error – we still need to add several components! One of these components is the product detail (or description) page – let’s run through what’s required in more detail.

Building the Product Card With the product gallery now set up, our shop is beginning to take shape. We could stop there, but who has ever used a site without some form of product detail page (or PDP)? It is an essential part of the site for the customer – it is where they can learn more about the product, the options available, pricing, and more. We will keep things simple for now and show just some basic details, but there is no excuse not to develop the content further should we go into production use.

41

Chapter 2

Creating Components

CREATING THE PRODUCT CARD This exercise is a little more involved – you will see it uses similar principles to the product gallery but begins to extend it by including a Svelte-driven conditional check. Let’s take a look at the steps required to create our product page: 1. To get started, create a new document, saving it as Product.svelte at the root of the \src\components folder. 2. Next, go ahead and add in this block of code – this contains some variable declarations, an import statement and (another) add-to-cart function:

3. You will recognize this next step – we need to add in the now-familiar placeholder folder for our styling:

42

Chapter 2

Creating Components

4. The last block to add in is the HTML markup – leave a line blank, and then drop in this code: {" window.alert('message from the click handler')}">Click me

This in-lines the event handler, but clicking it will produce the same result. That was a simple exercise that highlighted an important point: Which one do we use? Is one better than the other? I know some of you will have likely seen recommendations to steer away from using inline event handlers, owing to performance concerns, particularly when it comes to iterating through loops. This recommendation might be valid for other frameworks, but not for Svelte – it doesn’t matter which format you use! I can already hear the comments to the effect that this surely can’t be true – it is indeed true: you can use either format as you wish. To understand why, let’s first take a quick look at the code before understanding more about what happens under the covers with Svelte.

107

Chapter 5

Managing Events

It’s worth noting that although we’ve focused on using on:click, the same principles apply to other standard event handlers such as on:mouseover. We will touch on how to create custom Svelte events later in this chapter.

Understanding the Changes At the end of the last exercise, we posed a question: Which method do we use to create events? Inline or not? Well, as it so happens, you can use either – Svelte automatically decides which to use when it comes to completing the build process. In our case, we tried both formats in the demo – we started with a separate event handler that we could trigger by clicking a button and firing the on:click handler. This action triggered the handleClick function to display a message on-screen; we then tried the same event as an inline function, which gave us the same result once compiled by Svelte. To see what I mean, revert to a copy of the code where we used a separate event handler. Switch to the JS Output tab, and you will at first see a swathe of code – the key parts I reproduce here: function handleClick(event) {   window.alert("message from the click handler"); } ... class App extends SvelteComponent {   constructor(options) {     super();     init(this, options, null, create_fragment, safe_not_equal, {});   } }

108

Chapter 5

Managing Events

Now try the code again that had the inline form of the event handler – in the JS Output tab, we should see the same two functions: function instance($$self) {   const click_handler = e => window.alert("message from the click handler");   return [click_handler]; } ... class App extends SvelteComponent {   constructor(options) {     super();     init(this, options, instance, create_fragment, safe_not_equal, {});   } } As you can see, even though we’ve used two different forms of event handler, the resulting code is very similar, with only minor differences in the event handler itself!

Modifying Event Handlers In the previous exercise, we explored how to add event handlers using Svelte – it was easy to see from the demo that the syntax bears a remarkable similarity to standard JS. There will be occasions where we might want to override the default behavior; fortunately, we can do this with only a slight change required. Event modifiers in Svelte take this format: ...}> where the event modifier might be any one of several event modifiers listed in Table 5-1.

109

Chapter 5

Managing Events

Table 5-1.  List of event modifiers available in Svelte Event handler

Purpose

preventDefault

Calls event.preventDefault() before running the handler. Useful for client-­side form handling, for example.

stopPropagation

Calls event.stopPropagation() to prevent the event reaching the next element

passive

Improves scrolling performance on touch/wheel events (Svelte will add it automatically where it’s safe to do so)

Nonpassive

Explicitly set passive: false

capture

Fires the handler during the capture phase instead of the bubbling phase

Once

Remove the handler after the first time it runs

Self

Only trigger handler if event.target is the element itself

Source: Adapted from Svelte.dev website

A bonus is that these modifiers can be chained together – for example, we can do this: on:click|once|capture={...}. It’s all well and good talking about it, but the best way to understand how these modifiers work is to see them in action! We will do this in the next exercise, using two chosen at random from Table 5-1.

ADDING EVENT MODIFIERS Assigning an event modifier requires only a small change. To see how, work these steps: 1. First, browse to www.svelte.dev/repl – don’t forget the redirection that takes place!

110

Chapter 5

Managing Events

2. For our first example, we will use preventDefault – go ahead and add this code into the App.svelte panel on the left:

     submit

3. After a few moments, you will see a form appear on the right – click the submit button to see the response shown in Figure 5-2.

Figure 5-2.  Using preventDefault in a Svelte event 4. Go ahead and remove the |preventDefault text from the code, and then hit the Submit button once the screen has refreshed. You will see the same message appear, but if you click the OK button, the pane behind it will blank out. 111

Chapter 5

Managing Events

The second example we will look at is stopPropagation – as with standard JavaScript, this will have more of a pronounced effect. 5. Go ahead and save a copy of the code if you have set up an account with the REPL tool, or bring up a new REPL window. 6. As before, add this code into the App.svelte tab on the left:

Note  I’ve added some color to each div, to make it easier to see console.log('Outer div')}>.    Outer div     console.log ('inner div')}>     Inner div   

7. Go ahead and click the Outer and then Inner div tags – in the console log, you should see the name of the clicked div appear, as indicated in Figure 5-3.

112

Chapter 5

Managing Events

Figure 5-3.  The results of clicking each div when stopPropagation is used 8. Try removing |stopPropagation from within the code and clicking the div tags as before – you will get a completely different result! Adding an event modifier is an effortless change which can have a dramatic effect on the overall behavior of our code. Let’s take a moment to quickly explore the code we’ve created in more detail before moving on to looking at the next type of events in Svelte.

Exploring the Changes in Detail Event modifiers in Svelte are so easy to set up. The syntax for each modifier is the same; we add the | immediately after the on: directive name. Although event modifiers in Svelte are a cinch to add, they each apply the same effect as their JavaScript equivalents; in our case, we used preventDefault and stopPropagation. We started by creating a function handleSubmit(), which logs a message to the browser console – this we trigger using the on:submit event handler bound to the button element in our markup. We then switched to creating a more complex demo with two div elements; this time, we used two event handlers. Notice, though, we only applied the event modifier to the child div element to stop the outer event handler bubbling down to the parent and trigger clicks on both elements. Okay, let’s move on. We’ve focused on creating standard events and how to pass in modifiers to override the default action if needed. While this works very well, we should bear in mind that we may need to take a slightly different approach when writing components. The question is – how would that code differ compared to writing standard event handlers?

113

Chapter 5

Managing Events

Creating Events in Components It’s a good question: we could create events within components – if we triggered them, they would work fine. However, the parent (such as App.svelte) won’t listen to them and consequently won’t react. A good example could be to click an add-to-basket button; with an ordinary event, features such as mini basket counts may not respond (and therefore could become out of sync with the main basket). To get around this, Svelte has the createEventDispatcher feature – this allows the parent to listen for any instance where a child component triggers an event and responds accordingly. Hold that thought, though – there is a twist on this tale: What if we had to trigger an event held several levels deep rather than just one?

F orwarding Events Well, we could use createEventDispatcher, but this is likely to generate a lot of extra code. Instead, Svelte provides a shortcut called on:message. This shortcut allows us to forward events down from the parent through intermediaries to the target component, but the net effect means less code to write! It does raise an interesting question, though, as to whether this is better than simply passing events as part of a call to a native function, but for now, let’s take a look at an example of how we can use both on:message and createEventDispatcher to trigger events from nested components.

FORWARDING EVENTS To see how we can mix both createEventDispatcher and on:message, follow these steps: 1. First, browse to www.svelte.dev/repl – as before, don’t forget the URL redirection that will kick in! 2. Next, in the App.svelte tab on the left, add this code:

3. We need to add another component, so click the plus sign to the right of the App.svelte tab, and rename it to Outer.svelte. 4. Go ahead and add in this code:

5. There is one more component to add – Inner.svelte. Click the plus sign as before, but this time, rename the component to Inner.svelte. 6. Go ahead and add in this code:

  Click to say hello

You will note I’ve used my name in the greeting, but feel free to substitute yours if you like! 115

Chapter 5

Managing Events

7. After a few moments, we should see this button appear – if we click it, we get a suitable response from the inner component created in the demo (Figure 5-4).

Figure 5-4.  Response from the “forwarded” event This exercise shows how we can track and trigger events in a nested component from pretty much anywhere in our application. The only proviso is that we must maintain the forwarding chain (i.e., pass the event from component to component). Otherwise, a break means the event will not be triggered correctly. To understand how it works, let’s pause for a moment to review the code we’ve created in this demo in more detail.

Breaking Apart the Changes Forwarding events in Svelte can be seen as something of a double-edged sword – while it allows us to provide two-way interaction (a parent can pass to child and respond to events from children), we should take care over how we forward events.

116

Chapter 5

Managing Events

This means that we have to pass values down from the parent through each layer to the target child component when forwarding events. Granted, this is technically feasible for, say, six to seven layers, but it doesn’t mean we should do it. As a general rule of thumb, I would follow the same principle as for CSS styling – anything more than two to three layers, and we should reconsider the architecture of our site. Architecture aside for a moment, it’s worth exploring how our code works – we started by creating the App.svelte parent, where we imported an Outer component (more anon) before constructing the handleMessage function. The format of this function is essential as the real action is in the Inner.svelte component. The handleMessage function is effectively a placeholder for the sayHello() function within Inner.svelte. The trick to making this work is the on:message directive – this passes the handleMessage function down through to Outer.svelte, which then hands it off to Inner.svelte as a parameter. Once in Inner.svelte, we have a button tag, bound to which is an on:click handler that triggers the sayHello function. This next point is where it gets interesting. As we are in a component, we use the createEventDispatcher() function to listen out for the message response and dispatch an appropriate message on-screen using the alert handler in the parent App.svelte component. If we were to remove any part of the alert in App.svelte, or even the on:message tag in the Outer component, then we won’t see anything happen – even though we might call an instance of Inner.svelte, it won’t respond to clicks as the alert function is in the parent component, not the child!

In our demo, we used on:message with the function’s name to be passed down as a parameter. It’s worth noting that if we didn’t pass a parameter, Svelte will forward every message automatically.

A Point of Note In our demo, we used createEventDispatcher and passed functions inline as parameters – is there any difference between the two? If all you’re worried about is the result, then the simple answer is no: we can use both to produce the same effect. However, you might end up with a mix of code, such as this:

click 117

Chapter 5

Managing Events

While there is little difference between the two in terms of characters, you would need to remember which to use when working with Svelte. Having both styles could get messy – instead, it’s better to be more consistent and stay with one. The second method might require a little more code, but this is the trade-off we have to face when working with event forwarding. The equally important point is that passing down events as props more than six to seven layers deep is considered prop drilling and frowned upon by some as bad practice!

You can see some interesting comments on this subject on a StackOverflow posting starting at https://stackoverflow.com/q/61569655/15301592. Doniel Smith has also produced a more detailed article at www.donielsmith. com/blog/2020-­04-­21-­props-­vs-­event-­dispatcher-­svelte-­3/. Okay, let’s move on. We’ve covered standard events in some detail, but two topics remain, which play an equally important role in creating and managing events. I’m talking about managing life cycle events and creating actions – let’s first look at life cycle events and how they fit into the broader picture of event management.

Life Cycling Events in Svelte Over time, there will be critical moments where we might need to perform an action, during the life of a component. This life cycle starts when we create or mount the component and finishes once we have no further need for that component and it is destroyed. A perfect example of performing this action might be to fetch data when a component is mounted; we might also want to load a library used to perform a function essential to the component’s operation. As with many component-based frameworks, we can use several methods, depending on what point we need to intercept the component. These are listed in Table 5-2.

118

Chapter 5

Managing Events

Table 5-2.  List of Svelte component life cycle methods Svelte life cycle method

Function/use case – called when

OnMount()

The component is mounted on the DOM

OnDestroy()

Just before the component unmounts and is destroyed

beforeUpdate()

Before state updates the DOM

afterUpdate()

After state has updated the DOM

tick()

We can use this life cycle method at any time to help batch together changes to the DOM more effectively and reduce the number of instances we have to update the DOM

The theory of each type of life cycle event is all good, but nothing beats a little handson practice, right? With that in mind, let’s play with a couple of these event handlers to see how they work in Svelte.

W  orking with onMount If you’ve spent any time developing with the likes of React and Vue, then you may well be familiar with the first of our examples – onMount. This event works in much the same way as React; we can use it to intercept when a component is mounted and ask Svelte to execute an action during this process. The Svelte tutorial has a great example of how this works – we can use it to fetch data from a mock placeholder service, ready to render slots on-screen, for, say, a gallery. I’ve used it as the basis for our next exercise, with some minor tweaks – let’s look at how it works in action.

LIFE CYCLE METHODS PART 1: ONMOUNT To understand how onMount works in Svelte, follow these steps: 1. As from previous exercises, we will start by browsing to https://svelte. dev/repl to use the Svelte REPL tool – don’t forget the redirect that will kick in! 119

Chapter 5

Managing Events

2. In the App.svelte tab, go ahead and add this script block:

3. Next, we need to add some rudimentary styling, so the demo at least looks presentable – for this, skip a line, and then add in this code:

4. Our demo will be meaningless without some form of markup to display – for that, we need to add in this code, first leaving a line blank after the styling block: Photo album

  {#each photos as photo}                   {photo.title}        {:else}                   

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas sed odio id nulla gravida rhoncus. Suspendisse potenti. In volutpat nibh non tellus laoreet, vitae faucibus ipsum sollicitudin. Duis viverra pulvinar tempus. Phasellus odio nunc, imperdiet vitae diam quis, sollicitudin pretium massa. Donec molestie mauris id semper sagittis.



154

Chapter 6

Binding Elements

8. The next block of code takes care of rendering our contact form – we have the opening tags, followed by the name field:        *Name:

                       

9. Next comes the email address and message fields:

  *Email address:

      Your message:

10. Finally, we can add in a submit button and closing tags:            Submit        

11. Go ahead and save all of the files, and then close them.

155

Chapter 6

Binding Elements

12. Next, make sure you have started your Svelte development server, and browse to http://localhost:5000/contact – if all is well, we should see a page with the title, lead-in image, and text; we will see the all-important form further down the page (Figure 6-3), shown overleaf.

Figure 6-3.  The newly created form 13. Try hitting Submit now – if all is well, you’ll get a message saying there’s a problem, and Submit won’t let you go any further! If you do enter an email and name, you find all is well when hitting that Submit button. This was a prolonged, two-part exercise, but worth it! We’ve covered some valuable techniques while building this demo, so let’s rest for a moment and review the changes in more detail.

156

Chapter 6

Binding Elements

Understanding the Code in Detail So, what did we do? In part 1, we started by setting up the groundwork for our contact form – we installed the yup and svelte-yup plugins before updating the navigation in App.svelte by adding an additional for the contact page. In part 2, things were a little more involved; we started by creating the skeleton for the Contact.svelte page. We added in a script block to handle functionality; this first imported the two plugins. Next up came the function invalid to determine if we had correctly validated the submitted fields; if not, we flag them as such. As part of this, we then created a schema to determine how to check and validate our targeted fields. For name, we set it to expect a value of type string(), made it compulsory (or required()), and set it to be no more than 30 characters long, with a field name (highly original, I know!). We did something similar for the email field; we set it as a string() field, which was of type email() and required(). Next up, we then set an object to determine the default values for name, email, and yourmessage fields – note we do not use these for validating! We then set a couple of variables used for determining state before creating a formSubmit() function to check our fields are correctly validated. Last but by no means least, we then added in the markup – most of this is standard HTML, but it’s worth noting a couple of extras: •

We add the {schema} entry to tie each field back to the validation schema.



The {submitted} value is there to determine if the field has been submitted – it uses the two-way communication we’ve already talked about.



It uses the bind:value={fields.yourmessage} format to enable two-way communication, so we can use values as and when they are updated in the form.

Otherwise, the form is made up of standard HTML markup that you will find for each type of field we’ve used – hopefully, this shows that we don’t need to add too much extra code to our markup when creating forms using Svelte.

157

Chapter 6

Binding Elements

Note the presence of class:invalid={invalid("email")} – it looks odd, but this is purely to add a styling class. We will cover this more in the next chapter.

Summary Forms, forms... who loves filling them out? I certainly don’t, and I’m sure many of you would agree! Form filling is one essential part of any website – while they serve a purpose, the whole design can be a real hit-and-miss affair, with some companies getting it spot on and others leaving you feeling frustrated. Leaving the subject of frustrations aside, form creation is just one part of what Svelte has to offer when binding elements using this framework. We’ve covered several useful principles, so let’s take a moment to review what we have learned in this chapter. We started with a look at the core principle of data being driven from top to bottom and how this doesn’t apply to forms; we understood that frequently we need two-way communication when it comes to binding form elements. We then reviewed examples of how to bind different types of form elements, such as numeric inputs or multiline text boxes, before covering some of the other ways we can bind elements using Svelte. Next up, we then moved onto the subject of context – when binding to certain elements such as media, we explored how it was helpful to maintain a direct reference to the correct element using context. It means that if we have multiple elements, such as videos, we can target the right element. We then turned our attention to adding a new feature to our front-end store – this took the format of a new contact us page, with the beginnings of form validation. We covered how validating form elements can be an absolute minefield. We mentioned that in most cases, it is often more effective to use an existing validation library rather than create one from scratch! In this chapter, we’ve added all of the core features for our website. It’s time to make it look a little more stylish and presentable for our customers! At this point, things will get more interesting, as this opens up some real possibilities for us; it should be no surprise that I’m of course talking about adding styles. We have a lot to cover, so without further ado, let’s crack on and get our website looking presentable in the next chapter.

158

CHAPTER 7

Adding Styles We come to the point in the book where we add one of the most critical parts – styling! For some frameworks, this involves using lots of extra code to manage styling in-line, not so with Svelte. One of the great things about applying styles is that Svelte doesn’t expect anything complicated – just plain CSS added to the top of each file will do just fine. Of course, you can use techniques more associated with the likes of React and Vue, but it’s entirely optional. In previous chapters, we began exploring some of the techniques we would use in our demo, followed by applying a selection of those techniques to our demo front-end site. This time around, I’m going to flip things on their head and jump straight into styling the site! Don’t worry – there is a good reason for this: we will come to this shortly. First, though, there are some minor changes we need to make to the markup of our site, primarily around links; let’s dive in and take a look.

Making Some Small Adjustments Ordinarily, I would say that making changes to markup as a result of styling a site is not necessarily best practice: it feels like we’re using styling to dictate how our content should appear when it should be the other way round. That said, if we were to run the site now, we would see two errors appear: •

So far, we’ve used standard link tags – while there is nothing technically wrong in doing so, they do cause an issue with using stores. If, for example, we navigate from a product page back to the products listing, this can reset a Svelte store. It forces a complete full re-render of the page, which loses anything held in the Svelte store.



If we click a link from the front page, we might see this error appear in the console log (Figure 7-1).

© Alex Libby 2022 A. Libby, Practical Svelte, https://doi.org/10.1007/978-1-4842-7374-6_7

159

Chapter 7

Adding Styles

Figure 7-1.  Example of an unknown prop error Don’t worry though, the fixes for both are easy – we need to replace the href tags with tags and reconfigure the routing block in App.svelte to use a different tag. Let’s dive in and take a look at how in more detail.

FIXING THE ERRORS We have two key changes to make, so let’s make a start: 1. First, go ahead and open App.svelte, and then replace the block with this:

2. Save the file and close it.

As an alternative to the Route option we’ve used, we could use something akin to this syntax: ... . Both work equally well; it’s a matter of preference! 3. Next, open Product.svelte, and replace any instance of a:hover { color: #552200; text-decoration: none;  border-bottom: 5px solid #552200; position: relative;} a[aria-current="page"] { border-bottom: 5px solid #552200; position: relative; color: #ffffff; }

4. We need to position the main content and banner image on the page – this is covered by these two next style rules: section {  max-width: 60rem; } #banner { margin: 20px auto; width: 50%; display: table; }

5. The last handful of changes are for the modal dialog we added earlier in the book – go ahead and add in this code: .modal-background { background-color: rgba(0, 0, 0, .7) !important; } div.modal>div { display: flex; justify-content: center; } div.modal>div:nth-child(1) { justify-content: flex-end; } div.modal>div>button { background-color: #ffffff; border: 1px solid #c4c4c4; font-weight: bold; font-size: 18px; }

6. Save the changes and close the file – we will preview the results later, once more styles have been added.

163

Chapter 7

Adding Styles

Although we didn’t add that much in the way of code, the changes we’ve made in this exercise are still significant – we started by getting rid of what would be a lot of extraneous and redundant styles. We then removed a reference to CartLength, which was no longer required, before adding new styles to cover links, navigation, general placement on the page, and some overriding styles for the modal on the home page. Nothing too outrageous, as I’m sure you will agree! We still have a lot of styles to add, so let’s swiftly move onto the next part of this mega exercise: styling the pages in our demo.

Styling the Pages For this next exercise, we need to make changes to two of the four files in our demo – let’s take a look at the changes in more detail.

STYLING – PART 2: PAGES To update the styling for the two pages concerned, follow these steps: 1. The first change we will make is in Contact.svelte – we’re going to add in some additional markup that was missing from the original version. The code uses a standard HTML button element – go ahead and add in this reference at the start of the script block: import Button from '../components/Button.svelte'

2. With this in place, we can now switch out the standard button element for a custom component. Scroll down to almost near the end, and then replace the instance of button with Button. 3. Next, scroll back up to , and then leave a blank line after its closing tag (two lines down). Add in . Scroll down to the end, and then just before the closing tag, add a closing tag.

164

Chapter 7

Adding Styles

4. With the updated markup now in place, scroll back up to just before the opening tag, and add in this block:

5. The next change we need to make is in the Home.svelte file. Open the file in your text editor, and then scroll down to the closing tag. Go ahead and leave a blank line, and then add in this block:

6. Make sure you save both files, then switch to your browser, and head over to http://localhost:5000. If all is well, we should see something akin to the extract shown in Figure 7-2 (taken from the Contact page).

165

Chapter 7

Adding Styles

Figure 7-2.  An extract of the completed Contact Us page 7. Browse to Home – once there, you will see similar styling that uses the same rules we’ve applied in global.css. As in the previous exercise, nothing we added was unusual – everything was standard HTML markup or CSS styling. Adding standard markup or styling is what is so appealing about Svelte. It keeps things very simple, allowing us to focus on what is essential and reduce code bloat to a minimum. As you will see, this is a recurrent theme throughout the styling code for this site; to prove it, let’s continue with the following demo, which is styling the header and footer for our site.

166

Chapter 7

Adding Styles

Use of class: in markup Notice how we used class:invalid={invalid("email")} in our code? It might look a little odd, but this is purely to add a styling class. It’s effectively saying, “apply the class .invalid to this element, if the invalid("email") parameter is true, and not if it is false.”

Styling the Header and Footer This next exercise will be the largest of all four parts – we need to style all of the components! It will be a long one, but we will break it down into three sections; let’s begin styling the header and footer for our site.

STYLING – PART 3A: HEADER, FOOTER To style the header, we need to make several changes, so follow these steps: 1. First, open header – markup.txt from a copy of the code download accompanying this book. Copy and paste the contents directly over the ... block within the component. 2. Next, just before the tag, go ahead and add this code:

167

Chapter 7

Adding Styles

3. Go ahead and close this file – we’ve finished making changes to it. 4. Next, open the Footer.svelte file in your editor, and as per before, scroll to just before the opening tag, and then insert this block of styling:

5. Save the file and close it – we will preview the results later in this chapter. Parts 1, 2, and 3A complete: have a breather! Our demo didn’t cover anything unusual or complex; we added appropriate styling to make our header and footer look more presentable. Right, once you’re ready to continue, let’s move on with styling the next part, which is the call-to-action buttons for our site.

Styling the Buttons Adding call-to-action (or CTA) buttons to any site is an essential task – after all, how will customers be able to order any products, or submit feedback, for example? It would be a little awkward if they couldn’t; to remedy that, let’s cover the two button types we need for our site as part of the next exercise.

STYLING – PART 3B: BUTTONS To get the buttons styled, work through these steps: 1. First, open CTAButton.svelte, and then add this code in on the first line:

2. Go ahead and leave a line blank after the closing tag; it’s not obligatory, but it will make the code easier to read! 3. Next, open Button.svelte, and add the same code as per steps 1 and 2, but this time, we need to make one change – change width: 380px to width: 175px. 4. Save and close both files – we will preview the results when we complete the styling changes for the product pages and cart component. Phew, that was a straightforward exercise, in comparison to the others! It does bring up one important question, though: why two buttons? Well, the honest answer is probably due to laziness – yes, I know, not ideal! But it highlights one important point and something we could improve on later: we should reconfigure the Button component to accept a parameter value as its width and potentially a button type. This way, we can pass in that value, set it in CSS, and potentially deprecate one of the components. We can then use the button type to specify a priority – we might use primary for call-to-action buttons such as add to cart, with secondary for informational purposes only, such as submitting feedback. Okay, let’s move on. We have one set of changes left to do: the product pages (product gallery and individual product) and the cart component. Let’s move on with these as part of our final exercise.

Styling the Product Pages and Cart We reach the most critical point in this chapter: adding styles to our product pages and shopping cart! There is a fair bit of work to do, but we will also (in the spirit of continuous improvement) make a few changes to the markup at the same time. Okay, leaving that aside, let’s move on with making those changes, beginning with Product.svelte.

169

Chapter 7

Adding Styles

STYLING – PART 3C: PRODUCTS AND PRODUCT PAGES, CART We have a few changes to make to the product, products, and cart files, so let’s make a start: 1. First, go ahead and open product.svelte in your file editor, and then wrap the entire HTML block with tags. 2. Next, add a couple of blank lines before that opening tag, and then add the styling code from styling – product page.txt, in the code download accompanying this book.

Although we have a Back to Shop element on the page, we’re not going to style it here. We already have styles in the global.css file that will be sufficient. 3. Next, we need to add in a hack for the navigation – I will explain why later, but for now, go ahead and add this before the closing tag: let getShopMenuItem = document.querySelector("nav > a:nth-child(2)"); if (individualURL.indexOf("/product") != -1) {   getShopMenuItem.style.borderBottom = "5px solid #552200"; } else {   getShopMenuItem.style.borderBottom = "none"; }

4. At the same time, we can also improve on the markup – I know this isn’t strictly related to styling, but in the spirit of continuous improvement, we shouldn’t let that stop us! Scroll up to the start of the tag, and then add the code from styling – products page.txt in the code download for this book.

As before, I’ve compressed the styles for space reasons – the code download for this book shows the styles in an uncompressed format. 7. We need to make a couple of changes to the markup. Look for the start of the #each block, and then replace it with the code from the code download that accompanies this book. 8. Save the changes to Products.svelte, and then close the file. We have a couple more changes to make – this time they are in Cart.svelte. 9. Go ahead and open this file, and then scroll down to the closing tag. 10. Leave a line blank, and then add in the styling code from styling – cart. txt in the code download accompanying this book. 11. Save the file and close it – we’ve completed the changes required in this exercise. 12. Go ahead and browse to http://localhost:5000, assuming, of course, you have your Svelte development server running! Click Shop | any product name, and you should see something akin to the extract shown in Figure 7-3, with that product added to the cart, in Figure 7-4.

171

Chapter 7

Adding Styles

Figure 7-3.  An extract of the product page

Figure 7-4.  Our basket with a product added That was a lengthy exercise, but we can now celebrate: our site is pretty much now done! Although we’ve focused on styling (which should be pretty straightforward in itself ), there are a few things we should cover off; let’s pause for a bit to review the changes made in more detail. 172

Chapter 7

Adding Styles

Breaking Apart the Code Changes Over the last few pages, we’ve made a fair few changes to our code – most of it has been styling, but we’ve also taken the opportunity to tidy up some of the markup at the same time. This last exercise may have only covered three elements of our site. Still, it was the largest by far – we started by adding all of the relevant styling for the product page, including borders, font-weight, and general alignment. We then added a hack for our navigation to get around an issue with displaying the product page. If you take a look back at App.svelte, you will see that we put a element to help route requests to this page. The problem is that there isn’t a corresponding entry for it in the block just above; it means without this hack, we end up with a navigation bar that resizes each time we click a product link. Not a good experience! Next up came some changes to the

{@debug user} Hello, {user.firstname}!

3. Take a look in the console section on the right, at the bottom of the page – you might need to expand it by dragging the divider up. If all is well, we should see something similar to this: Object {   user: Object {     firstname: "Alex"     lastname: "Libby"   } }

4. Now try swapping out the {@debug user} line with this: {(console.log(user), '')}

205

Chapter 8

Unit Testing and Svelte

5. We still get the same values, but not in quite the same format – not only is this solution more verbose, but we don’t get the complete structure of the user object: Object {   firstname: "Alex"   lastname: "Libby" }

Debugging is, of course, an essential part of developing any website – I’ve lost count of the number of times I’ve used statements such as console.log() in my code over the years. Of course, if I’d had a dollar for each time I’ve used one, I would have retired long ago, but, hey, I digress! Back to reality – this might have been a simple exercise, and yes, we did it in a Svelte REPL: that was purely for simplicity. We can, of course, get similar results using console.log(), but @debug allows us also to get the structure (i.e., it’s the user object in this example), as well as the values – and both can be just as important. As an aside, we included input fields in this demo, purely so you can see the interaction – if we change the values in them, not only do the results change on screen but the console area updates automatically too.

As a test, try running the code in app.svelte.txt from debugging svelte folder in the code download, in a Svelte REPL. Notice how it renders both objects in the code? Okay, let’s crack on. There is one more tool we can use when testing (and analyzing) Svelte. It’s not a dedicated tool, but it’s free: why not use it? I’m talking about Lighthouse – it’s perfect for getting a feel for how our site rates against several aspects, such as performance and accessibility. Let’s take a closer look at what this might throw up – who knows? It might be a pleasant surprise or a complete shocker. Anything can happen!

206

Chapter 8

Unit Testing and Svelte

U  sing Lighthouse Spoiler alert – the results I got back when I ran it locally were better than I expected…! As a tool, Lighthouse has been around for several years; we can run it in several different ways, from using the command line to an NPM package or directly in a browser. So it’s perfect for getting a feel for how a site performs – it won’t give you acres of detail, but for a free tool, it’s a good starting point.

If you download it as a plugin, it may appear in a separate tab on its own. For this tool, you will need to run it in Chrome – it comes as part of the browser and is available in the DevTools area under the Audit tab. It gives us an option to select Desktop or Mobile – I chose Desktop and let it run. You can see the results I had back in Figure 8-6.

Figure 8-6.  The results of running a Lighthouse audit The vital thing to note here is that while it’s great to get to 100%, it is more about what Chrome highlights as potential issues we should address. With that in mind, I should set some expectations: •

I’ve only run this test once on my machine – you might not get the same results if you run it on your hardware, as they tend to vary from device to device. 207

Chapter 8

Unit Testing and Svelte



Running it a second time may give better or worse results – yes, this can happen!



We ran this test using development code – while the results are pretty good at this level, they will be even better if we were to run a production-ready version.

Lighthouse highlighted several changes that we should consider making – some were more complex than others; some we can change very quickly: •

Lighthouse reported a sizeable chunk of JavaScript that was unused – this included live reload. Of course, a lot of this will go once we move to production, but we should still consider analyzing the code to see if we can improve coverage.



Lighthouse highlighted an issue around CSS – it suggested we should inline some of it and defer the rest. Of course, we already do the latter by default, but could/should we have critical CSS inline?



Lighthouse complained of an issue with hidden text that we style using the blackjack font – we need to make sure it is still visible while it is reformatted.



We need to add explicit height and width values – this is worth considering, even though we might want to use responsive values to allow for multiple device types.



Links on the site don’t have a discernable name property.



Our site is missing a meta description tag.

There is a good selection of issues there – we can certainly address most (if not all) of those very quickly! Sure, more complex problems might surface, but bear this in mind: using Lighthouse is free of charge, so why not use it? Sure, we can do more complex things later once the site takes off, but for now, any improvement we can make for free has to be worth the effort and resources required to implement the change.

208

Chapter 8

Unit Testing and Svelte

Summary Testing, testing, 1…2…3… Okay, yes, we’re not on a set of some movie or trying to wire up some fiendishly complex communications system: that was my poor attempt at some testing-related humor! However, it does raise an important point, in that testing can feel frustrating if it is not done well; it might reveal all manner of different issues that make us think we should head back to the drawing board. But that wouldn’t be testing if we didn’t highlight and rectify any problems that appeared, right? Back to reality – what did we achieve in this chapter? We kicked off with a brief discussion around our strategy – the key point being the choice of testing suite and the approach we would take to testing the relevant areas of our demo website. We then moved onto setting up the testing environment using Cypress; this included installing support for the mount() option to allow us to test components in a more Svelte-like manner. We then switched to creating a simple test to confirm that Cypress was operating as expected before quickly exploring the file structure and how this would affect where we would store our tests. Next up came the most crucial part – we turned our attention to writing the various tests for the main areas of the website. It included the home page, content pages (a.k.a. Coffee, Our Story, and About) before tackling the shop, and product pages. We then rounded out the chapter with a quick look at how we might use Svelte’s debugging tool to help with narrowing down any issues that might crop up and use Lighthouse to help further perfect our code. We’ve now completed testing, so the next major milestone is… shock horror… releasing our code! Yes, we are technically at that point where we would release, but the reality is that our project would need further development before we could class it as true production-ready code. That said, it’s essential to see how we might perform a release – for this example, I will use my good friend GitHub Pages to assist; to see how, stay with me, and I will reveal all in the next chapter.

209

CHAPTER 9

Deploying Svelte Yikes, we’re coming ever closer to releasing our project into the wild! Although we’ve performed unit testing, in reality, our project would need more development work before we can class it as production-ready. Irrespective of what might be left to develop or test, the principles of deployment of a Svelte site are still the same. This chapter will examine how to prepare and deploy our site onto the Internet. We’ll cover off some of the options available for hosting, as well as how we might automate the deployment process. As a bonus, we’ll even tack on a custom domain name to boot! Okay, let’s start with some simple checks: we’ve done a lot of this in the previous chapter, but it’s an excellent way to do a final sign-off before we commit to pushing code live.

Doing Final Checks Ladies and gentlemen – it is time… Yes, indeed, it’s where we hit reality and unleash our site onto our customers! Okay, perhaps that was a little too dramatic, but the reality is that we’ve created our development site, tested it, and now it’s time to make it ready for release. Sure, there will be a lot more work we would need to do if we were to release it for real, but a release is still a release – we still need to decide how this will happen. I am sure that you will be familiar with the kind of steps we might take when it comes to releasing code – we should test it, perform checks to ensure nothing obvious stands out that shouldn’t be there, and make sure it performs as expected. As a developer, I know this is something you will have done dozens of times – it’s still a little bit of an anxious time, as we can never be sure if everything will work as expected!

© Alex Libby 2022 A. Libby, Practical Svelte, https://doi.org/10.1007/978-1-4842-7374-6_9

211

Chapter 9

Deploying Svelte

We’ve already covered the unit testing process in the previous chapter (and in a more real-world environment, we would also execute stages such as pen testing or acceptance testing). Once we’ve completed this step, we can also do some preparatory checks to ensure everything is present and that we didn’t miss anything in one of the testing procedures. Yes, I’m probably supercautious at this time, but the more checks we do, the less likely something will slip through! We need to add one more component – this is not an essential part of the shop, though, but more for our sanity. What is this component, I hear you ask? It’s a disclaimer – we’re about to release something into the wild, and you can be sure someone will try to purchase from the store. It is just to let them know that this is a dummy store, and if they are foolish enough to try to buy something, well, we can at least say that we did warn them! It’s a simple component to set up and add to our store, so without further ado, let’s dive in and take a look at the code in more detail in the next exercise.

ADDING DISCLAIMER To set up the Disclaimer component, follow these steps: 1. First, crack open a new file in your editor, and then add this styling block:

2. Leave a line blank, and then add in this element:   This is a test site only - please note that no orders will be accepted

212

Chapter 9

Deploying Svelte

3. Go ahead and save the file as Disclaimer.svelte, in the \src\ components folder. 4. Next, crack open App.svelte, and then alter the first import statement to show this: import {   Products,   Footer,   Header,   Product,   Cart,   Disclaimer } from "./components";

5. Scroll down to the closing element, and then add in a call to the Disclaimer component, as indicated:   Our Coffee   Contact



6 . Crack open index.js from the \src\components folder, and then add this line immediately below the last import statement: import Disclaimer from "./Disclaimer.svelte";

7. At the end of the file, you will see an export statement – add the reference to Disclaimer, as indicated: export { Products, Footer, Header, Product, CartLength, Cart, Disclaimer }

8. Save and close all open files – we have completed the changes. 9. Switch to your browser, and then head over to http://localhost:5000/. If all is well, we should see a red banner appear, with the warning (Figure 9-1).

213

Chapter 9

Deploying Svelte

Figure 9-1.  The newly added disclaimer on our site That may have been an easy exercise, but an important one – you can be sure that someone will try to buy something from the site, thinking it should be a real one! We can’t stop them from trying, but we can make it more transparent that they won’t receive anything they try to order from the shop. Okay, let’s move on. It’s time for us to start breaking apart the deployment process. We have a few steps to cover; let’s start with choosing our hosting provider.

Understanding the Deployment Process We now have a working site for which we’ve done our final checks: it’s time to make it live! Okay, in reality, we probably wouldn’t want to publish our site as it stands; it’s still very much a development project and needs a lot more work before we could put it in front of paying customers. Nevertheless, it’s still important to consider the principles of how we might go about publishing our site, ready for when we can indeed make it live. There are several different ways to publish our site, depending on whether you might want to use a provider such as AWS, Netlify, Surge, Now, or Vercel. We have to consider several factors such as resilience, compatibility with technologies we use, costs, security, and so on – clearly something we should not rush! For this book, I’m going to use GitHub Pages – there are several reasons for this:

214



It includes native support for SSL, which is easy to enable – it’s something Google looks for by default for SEO purposes.



GitHub Pages is free, as long as you use an open repo – this is fine for our needs (but see the comments shortly).

Chapter 9

Deploying Svelte



It doesn’t limit the number of build minutes available (as other hosts such as Netlify do) – as long as you don’t need to use GitHub Actions, which we don’t.



I already have a good handful of GitHub repos, so I don’t want to introduce another hosting facility into my collection!

I will say that choosing GitHub is purely my preference – please feel free to use an alternative host if you prefer. The focus of this chapter is about seeing our site available in the wild and not the specifics of how we host it. With our host provider chosen, let’s turn our attention to setting it up – this does require a fair few steps, but thankfully most of them will be a one-off, assuming all goes well! In a nutshell, we have to •

Set up a GitHub Pages account



Create a working area for cloning the repository



Upload content

As a bonus, I will also tack on a custom domain name to see how our site will look in real life. Yes, it won’t be ready for actual production use, but it will at least give us a flavor of what to expect. Okay, let’s crack on with setting up a GitHub site as the first part of this multistage exercise.

Setting Up the Hosting Provider The first stage in our multipart demo is to set up a GitHub account – you can, of course, use an existing one, but it will make configuring a little trickier! Creating a new one from scratch means keeping the setup nice and clean and not worrying about affecting any existing code or configuration.

215

Chapter 9

Deploying Svelte

Before we crack on with setting up our repository, there are a couple of assumptions you need to bear in mind: •

For this exercise, I will assume we are using the username smallcoffeecompany; you will need to think of a suitable name and swap this in as appropriate.



I’m also assuming that you will create a new account and repository for this exercise; you can use an existing one, but it will make things more complicated!

With this in mind, let’s make a start with setting up our GitHub space.

PREPARING THE HOST To set up a new repository, please follow these steps: 1. We’ll start by creating a new repository – for this, browse to https:// github.com, and click Sign Up in the top right. 2. Go ahead and follow the instructions provided on-screen, including adding an email account (it’s worth it!) – make sure you take note of the details you use for your account. Once done, sign in with your new account, and make sure it is validated. 3. Next, we need to create our repository – click the + sign in the top right and then New repository. 4. On the next screen, the Owner field will be your account name. Enter a repository name in the format username.github.io, where the username is your chosen username on GitHub. 5. If you want to fill in a description, then go ahead and do so – it is not compulsory for this exercise. 6. Next, choose Public as the repository type, and click the checkbox against Add a README file to initialize the repository with a readme file. 7. For the Add .gitignore option, choose Node, and set the Add a license to MIT.

216

Chapter 9

Deploying Svelte

8. Click Create repository – if all is working as expected, we should have an empty repository, similar to the screenshot shown in Figure 9-2.

Figure 9-2.  Our new repository on GitHub Excellent – at this point, we should now have a working repository, ready to accept our uploaded code. The upload process is very straightforward – we could automate it, but I will use the manual format for this book. Let’s look at what’s involved in more detail, beginning with a simple but all-important check.

217

Chapter 9

Deploying Svelte

Checking the Default Branch Although we have our repository in place, there is a straightforward check we should do before we upload code. We need to make sure that we’ve set the correct default branch in GitHub – if we were using an automated approach, this is crucial to ensure code deploys correctly and is visible when rendered in a browser. For this chapter, I want to keep things simple – it does mean that this may not immediately match your needs. Therefore, I would recommend treating this step as an aide-memoire and that when you come to check your setup, you set (or create) a branch name that suits your needs. We will use the default of main; however, I should point out that this is the right branch for our needs. You may prefer to use something different and should adjust the code accordingly. It’s easy to check which branch is set by default from within GitHub – let’s take a look at how.

CHANGING THE DEFAULT BRANCH To change the branch, follow these steps: 1. First, navigate to your site’s repository, or switch to it if you still have it open in a browser window. Then, under the repository name (and in the menu to the right), click Settings. 2. In the GitHub Pages section, click the link to go to the Pages configuration. 3. Ensure the value set in the Source drop-down list is main – as indicated in Figure 9-3.

Figure 9-3.  Checking the branch settings in our repository 4. Click Save – the site is ready to host content. 218

Chapter 9

Deploying Svelte

It might seem as if we’re a little too cautious, but not checking could mean the difference between us having a working site and potentially a blank page or errors showing on screen! In our case, we shouldn’t have had to make any changes, but your needs might be different, and that you should adjust accordingly. Okay, let’s crack on. The next step is where things start to happen. It’s time for us to upload our code to GitHub, so we see the finished site on screen.

Deploying Content to Production One of the great things about Svelte is the deployment process – when it comes to uploading code into GitHub Pages, we might typically use a package called gh-pages. It was designed to simplify the uploading process; the weird thing is that it is overkill for our needs! Why? There is a straightforward reason – Svelte sites, when built, compile down to standard JavaScript, CSS, and HTML markup. It means that we can use the usual git add and commit commands to upload content; we don’t have to use any other package! As anyone who knows me personally, I’m very much a fan of keeping things simple – after all, the more complex it gets, the more likely it will go wrong, right? Before we get stuck into uploading code, there are a couple of housekeeping points you need to be aware of: •

I’m assuming that you have Git already installed for your platform, along with Git Bash; if you don’t, then please go ahead and get it installed before you continue with the exercise.



I’ve already set up a GitHub repository under https://github. com/smallcoffeecompany – the steps in the demo will use this as an example. Please substitute smallcoffeecompany with your GitHub repository username when completing the exercise.

If you need any help with installing Git, then please refer to https://git-­scm. com/book/en/v2/Getting-­Started-­Installing-­Git, which details the process for most popular platforms.

219

Chapter 9

Deploying Svelte

Okay, with that bit of housekeeping out of the way, let’s move on to the exercise. Figure 9-4 gives you a flavor of what to expect once we’ve uploaded all of the code and configured the custom domain.

Figure 9-4.  The completed site, hosted in GitHub Pages Now that we know what it should look like, let’s get stuck into setting up Git ready for us to upload code to the new site.

220

Chapter 9

Deploying Svelte

SETTING UP GIT To upload our code to GitHub, please follow these steps: 1. First, fire up a Git Bash terminal session (and not a regular Node.js terminal), then change the working folder to our project area. 2. Once changed, enter this command and press Enter – this will build a production-ready version of our site: npm run build

3. Switch to your GitHub repository area in your browser, and then go to the main page. Click the green Code button, and then copy the URL in the HTTPS tab. Revert to the Git Bash prompt, and then enter this command: git clone >

4. Once cloned, go ahead and copy the contents of the public folder from our project area into this new Git folder. 5. Next, enter git status at the Git Bash prompt to verify that Git has marked the new files for tracking. 6. At the prompt, enter these commands one after another, pressing Enter after each one: git add . git commit -m "initial commit" git push

7. Once committed, go ahead and browse to the site in your browser – if all is well, you should see it published. You can see an example of how it should look with my version, available at https://smallcoffeecompany.github.io, as shown at the start of this section. Our site is now finally live! Yes, okay, it’s not ready for production use, but it’s the principle that matters here: we can go back and develop the site further, safe knowing that we have a mechanism to publish it.

221

Chapter 9

Deploying Svelte

That aside, we’ve covered some essential points as part of this process – let’s take a moment to review the changes we made before cracking on with adding the bonus domain name.

Breaking Apart the Changes Although we could have automated the upload process, I’ve deliberately kept things simple, using techniques that I’m sure you will already be familiar with as a developer. Nothing should stop you from automating the process, though – how will depend on your own environmental needs. The fundamental principle here was to show that we don’t need any extra tools to achieve this process. Talking of process, how did we upload the code? We started by running npm run build in the project folder; this creates a production-ready version of our site as static HTML, CSS, and JavaScript. I say “production-ready” because our site does need extra work to get it there; it’s the process that counts at present. Next up, we then used Git to clone a copy of our GitHub Pages site before transferring a copy of the contents of the /public folder from our project area into the upload space. Of course, we would have created the GitHub site first in an ideal world, but that might add a little extra complexity; having a separate area means we don’t risk uploading code that isn’t ready. We used standard Git commands to create the merge request for the last stage before using git commit to push it up to our site. The code is visible straight away; this isn’t an issue for us as we’re working in a development capacity. You might want to create a separate branch first so that the master branch can still operate. At this point, we checked the site – assuming we encounter no issues, we successfully viewed the site in our browser at the new GitHub Pages address. Okay, here comes the proverbial icing on the cake: adding a domain name! Svelte doesn’t have to run with one: Svelte will run quite happily without one. I like to add one in, though, to give the site an extra sense of realism. To learn how to, let’s take a look at the steps involved in more detail.

Adding a Custom Domain Name Adding a custom domain is easy when using GitHub Pages, although we may have to factor in a 24-hour delay in the process. There are several benefits, though, in doing this process, irrespective of what tooling or framework we use: 222

Chapter 9

Deploying Svelte



Using a short domain name is more memorable to customers, rather than what is effectively a custom subdomain – it inspires more confidence and is better for SEO purposes.



An external domain name can be purchased cheaply, which makes for no excuse when it comes to creating a site.



Having a subdomain doesn’t suit every purpose – after all, why would you have a domain name such as coffee.github.com if you owned a coffee shop? GitHub Pages domains may serve technical people such as developers, but not your average Joe in the street!

Let’s take a look at the steps we need to run through to get our site set up with a custom domain in more detail.

Before we start with the exercise, please make sure you have the means to update DNS; you might need to get assistance if you don’t have access. Also, references to SSL in this text are generic: GitHub Pages uses the more secure TLS version for encrypting your website. ADDING A DOMAIN NAME I will assume you have a registered domain name for this exercise – it can be an existing one or one registered anew. If it is a new registration, you may want to wait 24–48 hours to allow it to propagate around DNS before working through these steps: 1. First, browse to your GitHub site using the format https://github. com/. 2. On the main page, click Settings, and then scroll down to Custom domain. 3. In the Custom domain name field, enter the name of your chosen custom domain (in my case, I used smallcoffeecompany.co.uk – see Figure 9-5), and then hit Save.

223

Chapter 9

Deploying Svelte

Figure 9-5.  Confirmation that GitHub Pages has saved our custom domain

This action will create a commit that adds a CNAME file in the root of your repository. 4. Next, navigate to your DNS provider and create an A record – use these IP addresses; you may find you need to create four separate A name records for each of these IP addresses: 185.199.108.153 185.199.109.153 185.199.110.153 185.199.111.153

We’re using A records here, as the IP addresses are known and stable; CNAME entries are name aliases that map to other names. 5. To confirm that your DNS record configured correctly, use the nslookup command – enter this in a terminal session: nslookup

If you are using Linux (or potentially Mac), then you can use this: dig EXAMPLE. COM +noall +answer, where EXAMPLE.COM is your domain name.

224

Chapter 9

Deploying Svelte

6. It will display something similar to the responses shown here: Non-authoritative answer: Name:    smallcoffeecompany.co.uk Addresses:  185.199.108.153             185.199.111.153             185.199.109.153             185.199.110.153

7. We have one more change to make, but when you can do it will depend on how quickly GitHub Pages completes a step. This step should be completed relatively quickly but can take time to update (Figure 9-6).

Figure 9-6.  SSL certificate provisioning in progress

You might want to refresh the page to check the status: the next step can be completed once GitHub enables the checkbox. 8. Once prompted, scroll a little further, and you will see an Enforce HTTPS box, similar to Figure 9-7. Go ahead and tick it to force access to be HTTPS.

Figure 9-7.  HTTPS access is now set 9. In a separate tab, go ahead and browse to your new site – as an example, Figure 9-8 shows how my version looks, under the new URL of www. smallcoffeecompany.co.uk. 225

Chapter 9

Deploying Svelte

Figure 9-8.  The completed site with the new custom domain name (highlighted) Yay! Our site is now complete! This simplicity is one reason why I love using GitHub Pages – it takes a lot of the hassle out of tasks such as setting up SSL certificates for us. This step marks the final part of getting our core site live, but by no means the end of the project: we have more to cover in future chapters. In the meantime, though, let’s pause for a moment to review the changes made in this chapter.

Breaking Apart the Code Changes Having a no-code exercise makes a nice change for once! Okay, so I might be being a little frivolous, but that aside, let’s take a look at the steps we covered in the last exercise in more detail. We kicked off by browsing to our GitHub Pages site settings before adding in the custom domain and allowing the change to take effect. At the same time, we noted that this would create a CNAME record in our site automatically – this is required to redirect content correctly with our domain name and not display it as a GitHub Pages URL. 226

Chapter 9

Deploying Svelte

We then added the DNS entries that point to GitHub Pages into our DNS – you will notice that we use four entries to provide redundancy, which is standard practice with any GitHub Pages site. However, the preference is to use A records for this, as the IP addresses are known and stable. We then did a quick nslookup to verify that DNS had been updated (it’s not noted in the exercise, but you might find this takes a few minutes to complete before you get the expected result). We rounded out the exercise by enabling SSL support – GitHub uses TLS for this purpose which is more secure but does precisely the same thing. Once we provisioned the certificate, we switched the site over to use HTTPS by default – it means that the site is only available via a secure URL which is standard practice nowadays, particularly for SEO purposes!

Taking It Further We’ve now reached the point where our site has been deployed and is available for all to see – the question is, what next, I wonder? Well, we have a couple of projects still to come in future chapters, but there are a few more immediate questions we can answer: •

Automation – can we improve on the deployment process?



Is the folder structure we’ve used sufficient for our needs, or can we improve on it?



We elected to use the main branch in our repo – is this the best option?



We’ve deployed code to our GitHub repo, but what about tidying up the front page of the repo, so others can see how to install and run our (test) site?

Hopefully, you can start to see a theme of continuous improvement running here – I’m a firm believer in the principle that a site is only finished when it no longer serves a need, not when we’ve finished writing code. To see what I mean, let’s take the first point as an example – how could we automate the deployment process? Let’s work through a potential answer to that question as part of our next exercise.

227

Chapter 9

Deploying Svelte

This walkthrough is a purely theoretical exercise designed to show how we might automate the process; it will likely need tweaking before using it in anger. WALKTHROUGH: AUTOMATING THE DEPLOYMENT PROCESS To understand how we might start to automate the deployment process, let’s walk through some example steps using code from the DevSamples website: 1. We briefly mentioned using gh-pages earlier in this chapter – if we were to automate deployment, then the first step would be to install it via a Node.js terminal session: npm i gh-pages

2. To upload content requires we provide certain details, such as the URL of our repository, username, and email address. We can achieve this by creating a script that might look like this (and which would live at the root of our project area): var ghpages = require('gh-pages'); ghpages.publish(   'public', // path to public directory   {     branch: 'gh-pages',     repo: 'https://github.com/username/ yourproject.git',     user: {       name: '',       email: ''     }   },   () => {     console.log('Deploy Complete!')   } )

228

Chapter 9

Deploying Svelte

It’s worth noting that we must provide both of these details. Otherwise, you might end up with some weird results, such as other GitHub accounts appearing to add commits when they should be! 3. We need to make sure that links in the index.html file at the root of \public contain relative paths; otherwise, links might not work correctly:

        Small Coffee Company | The home of great coffee            



The links are relative by default – this step is to catch any changes made to the default markup since we provisioned the initial site. 4. We’ve already done this next step in our manual deployment, but the same needs to happen if we automate it: /node_modules/ # /public/build/ .DS_Store

229

Chapter 9

Deploying Svelte

5. This final step would be to run through commands similar to these to first build a production version of our site before committing it to our repo: npm run build git add . git commit -m "initial gh-pages commit" git push origin gh-pages node ./gh-pages.js

6. If all is well, we would see our site updated at https://github. io/. Seems pretty straightforward, right? We first install the gh-pages library to aid with uploading content and then create a script that takes care of the upload process. At the same time, we make minor changes to ensure we’re not pushing up irrelevant content. Other than this, we can use standard commands to create a merge request and push it to our repo. The critical point here is the use of the ghpages script – the ghpages library takes what we push up to the repo and then creates a temporary copy of the repo. Next, it creates a temporary copy of the target branch (in this case, ghpages) before pushing any changes to the branch.

You can learn more about this library at https://github.com/tschaub/gh-­ pages. Creating a ghpages script is only the tip of the proverbial iceberg, though; these changes would allow us to go further. We could, for example, add a step in the package. json that runs most (if not all) of the steps automatically – it would rely on us passing suitable parameters for the commit message and hard-coding the default branch into the script. We might even go as far as uploading the source code (or at least the relevant folders) and then using a process such as GitHub Actions and a YAML configuration file to build the site for us. Much of what we could do will, of course, depend on your circumstances – suffice to say it’s something to think about for future development! 230

Chapter 9

Deploying Svelte

To get a flavor of how GitHub Actions could work (in a general context), take a look at this article by Frontend Weekly on Medium: https://medium.com/front-­ end-­weekly/ci-­cd-­with-­github-­actions-­to-­deploy-­on-­github-­ pages-­73e225f8f131.

S  ummary The publishing of any site can be a tense moment – we know that site development is finished (at least for this iteration). Still, equally, there is a certain amount of nervousness about how our customers might take to our newly published site. Customers are fickle beasts at the best of times; we can’t dictate what we want them to do (despite trying!), but we can make sure that the publishing process is painless. We’ve covered several valuable tips in this chapter to that effect – let’s take a moment to review what we have learned. We kicked off by exploring one final check step to ensure we haven’t missed anything obvious. We talked about the fact that this is probably me being supercautious, but a last check is equally an excellent way to sign off before final publication. We then went through the deployment process, beginning with understanding the critical steps before setting up our base site with GitHub Pages. We then moved onto creating the deployment steps and pushing our code up before checking to ensure we can display our site as expected on screen. As a final step, we added a custom domain name to give our site a little extra realism. We then finally rounded out the chapter with a brief look at some of the “next steps” we might take, principally around refining the deployment process to make it even smoother for future development. At this point, we can breathe a sigh of relief – our site is up and running! The bad news is that we still have more we can do: we’ve created a shop front, but how will people pay for our products? We can’t let them go for free, so clearly we need to do something: we need a payment process! I’ve got the perfect candidate that can help here, as well as show off how well Svelte works with third-party libraries – stay with me, and I will reveal all in the next chapter.

231

CHAPTER 10

Working with External Libraries One of the key benefits of using Svelte is that we can use it in conjunction with other libraries or frameworks – Svelte can work with any library, including using components created for other frameworks, such as React. That’s a bold statement to make, so in this chapter, we will put this theory to the test and work with some external libraries to see how Svelte can interact with them. First, we’ll create demos using some Svelte third-party libraries before finishing up using an external library to supplement our ecommerce front-end project. At the same time, we’ll explore how we might live up to that theory – can we import a component from another framework into Svelte? Before we get to answer that, we must start somewhere – let’s begin with a look at how we can import external libraries into Svelte.

Importing Libraries into Svelte By now, I’m sure you will be familiar with the process of importing NPM packages, such as Svelte – we’d use a typical import such as import { setContext } from "svelte", right? I won’t dwell on the subject for fear of teaching something we already know! However, we have a few more options open to us when importing external libraries (such as the Tailwinds CSS library, from www.tailwindscss.com). The great thing about them is that we can make them as straightforward or as complex as we like – let’s take a look at them in order of complexity, as shown in Table 10-1.

© Alex Libby 2022 A. Libby, Practical Svelte, https://doi.org/10.1007/978-1-4842-7374-6_10

233

Chapter 10

Working with External Libraries

Table 10-1.  Options available to import third-party libraries Method

Example

Importing a library using script tags

Usually into \src\public\index.html, and not into the component. It works, but take note that we can't maintain a clean separation of concerns. So, the imported library will be in the index.html while you work in a component – a neater arrangement is to use svelte:head to import the library directly into the component

svelte:head

A typical example looks like this:



onMount()

Using onMount() is more complex and better suited to occasions where you need a callback – it also doesn’t work if you are using Svelte in a server-side capacity: onMount(() => {   const interval = setInterval(() => {   console.log('beep'); }, 1000);     return () => clearInterval(interval);   });

Using an action

Svelte actions allow us to set up any third-party library or framework and make it reusable with the use: attribute:

Hello from our action!

So, how does one choose which to use? A lot of this will depend on your requirements; if you need to provide a callback, then onMount() is best. Alternatively, if you need to use the library in multiple places, I suggest using a Svelte action. In many 234

Chapter 10

Working with External Libraries

cases, though, I suspect that simply importing the library into the head of your code (either directly in \public\index.html) or using svelte:head will work fine. Let’s put some of this newfound knowledge to good use and create a few demos – they will be simple but are designed to show some of the ways we can import third-party libraries into Svelte.

Testing Compatibility with Svelte Over the following few pages, we will put together some simple demos that show the various ways to import or reference third-party libraries or frameworks within Svelte. We will build all of them in Svelte’s REPL playground for convenience – let’s take a look at each of them in turn, starting with importing CSS.

DEMO 1: IMPORTING CSS WITH HEAD To set up our mini photo album, follow these steps: 1. First, head over to www.svelte.dev/repl – go ahead and copy this code into the App.svelte tab on the left:

  

2. Next, go ahead and add a new tab to the right of App.svelte – rename this to flat.svelte. 3. Go ahead and extract a copy of flat.svelte.txt from the code download for this book (which you can access by clicking the Download Source Code link located at www.apress.com/9781484273739), and then copy the contents into the tab created in the previous step. 235

Chapter 10

Working with External Libraries

4. If all is well, we should see a date box appear on the right in the Results tab – click the icon to the right to show a date picker, as indicated in Figure 10-1.

Figure 10-1.  A date picker component using the svelte: head directive I don’t know if it’s me, but there’s something about this demo that evokes memories of using jQuery UI from years ago – anyone remembers using that library? So now there’s a blast from the past! If we leave aside trips down memory lane for the moment, this demo shows a great way to import content such as the Tailwind CSS library while still keeping it within the component. We could have added the statements in the head within the \src\public\index.html file, but that means it’s spread over multiple locations, making for a less clean approach. Okay, let’s crack on with the second demo. This one references the onMount() event handler to allow us to import content as before, but this time provides the opportunity to add in a callback as part of the process.

236

Chapter 10

Working with External Libraries

DEMO 2: USING ONMOUNT To set up our mini photo album, follow these steps: 1. First, head over to www.svelte.dev/repl – go ahead and copy this code into the App.svelte tab on the left:

2. Leave a line blank, and then go ahead and add in this styling block:

3. Last but by no means least, we need our markup – miss a line, and then add in this code: Photo album

  {#each photos as photo}                   {photo.title}     

237

Chapter 10

Working with External Libraries

  {:else}          

loading...

  {/each}

4. If all is well, we should see our photo gallery appear on the right after a few moments (Figure 10-2).

Figure 10-2.  The demo photo album created using onMount()

238

Chapter 10

Working with External Libraries

This demo shows off a great way to source third-party information or content and effectively import it into our Svelte code. It’s suited for those occasions where you might want to execute that callback function we talked about earlier while still maintaining a mechanism that degrades gracefully if the external content is unavailable. Moving on, this next demo provides an excellent effect we can use on websites and online applications – remember the days when we had to use typewriters? Yes, it might seem a long time ago, but old-school apparatus often works better and more reliably than modern-day technology! That aside, let’s take a look at how we can replicate the typewriter effect as part of the next exercise.

DEMO 3: CREATING A TYPEWRITING EFFECT To set up a typewriter effect, follow these steps: 1. First, head over to www.svelte.dev/repl – go ahead and copy this code into the App.svelte tab on the left:

This is our typewriter action

2. Next, click the plus sign to the right of this tab and add one called typewriter.js: import Typewriter from 'typewriter-effect/dist/core'; export function typewriter(node, text) {   var typewriter = new Typewriter(node, {     strings: text,     autoStart: true,     loop: true   }); }

239

Chapter 10

Working with External Libraries

3. If all is well, we should see this effect in the Result tab, as shown in Figure ­10-­3.

Figure 10-3.  Creating a typewriter effect Over the years, I’ve always maintained there is more than one way to crack a nut – this is no different with Svelte and importing third-party content; we’ve seen a few ways to achieve this in the last few demos. So let’s take a moment to review the code we’ve set up to see how each works in more detail.

Exploring the Code in Detail So, what did we create? We started using the svelte:head function to import the Tailwind CSS library and create a simple date picker component in the first of our three demos. We could have built this by linking to the same CSS file from within \src\public\index.html, but this gets messy if we wanted to reuse this component elsewhere. Inside flat.svelte, we first import the Flatpickr component from svelte-­ flatpickr, before setting up the flatpickrOptions configuration object with some appropriate values (such as the host element, #flatpickr). We then linked in the Tailwind CSS library using svelte:head, before setting up the relevant markup for our picker component. If you look closely, you will see that TailwindCSS uses a similar approach to Bootstrap. It works well, but you have to be careful; otherwise, you can overload content with too many classes! Moving on to demo number two, and this time we use the JSONPlaceholder feed to create a dummy photo library. This time, we’ve used onMount(), as the content won’t already be available (unlike TailwindCSS). Instead, we’re fetching the content and assigning it initially to the variable res, before converting it into valid JSON once the fetch is completed. The rest of the demo is standard markup and styling, but note that we use the Svelte #each command to iterate through each photo, importing each thumbnailUrl and title into the markup.

240

Chapter 10

Working with External Libraries

In the last demo, we go back to the good old days of hardware! This time, we replicate the typewriter effect when rendering text on-screen. We first import a typewriter script file that imports the Typewriter library before exporting a new instance with appropriate settings. In App.svelte, we then create an H1 tag, to which we apply the use: statement; Svelte looks for the same name in the exported file as is provided in the use clause. If it finds it, it will reuse the code from the exported file – this allows us to create a one-time setup, which we can reuse as many times as we want in our code. Before we go any further, there is one crucial point I want to cover off – server-side rendering (or SSR) and how this might affect the use of external libraries. SSR has an impact since onMount() is not available; it also opens a broader question about whether we need to use SSR when working with Svelte.

Working Client Side vs. Server Side If you’ve spent any time working with frameworks such as React, then I suspect you will have come across the term server-side rendering at some point. In a nutshell, it’s the difference between building the code client side and server side. We can defer many more expensive tasks such as JavaScript rendering when running client side, whereas server side will build everything but come at a higher cost in terms of resources. So, how does this affect us, particularly when we’re using third-party libraries? There are several reasons why we might use SSR generally, but the biggest one is SEO. If we rendered our code server side, then the crawler can download our site as fully constructed HTML (including some JavaScript – not all); it means we don’t need to execute JavaScript client side to render the code. In theory, we could build a Svelte application entirely server side, but it would almost certainly render as 100% pure static code; users expect a certain amount of interactivity, making this approach impractical! To get around this, we would need to perform dynamic rendering – effectively a mix of server and client side. The former is perfect for the content which can remain static while using the client side to create the interactive content. This approach does have some limits, though. For example, SSR code cannot interact with client-side code and vice versa; each must execute independently.

241

Chapter 10

Working with External Libraries

Why Is Svelte Different? Remember how, back in Chapter 1, I said Svelte is different? Unlike other frameworks such as React, Svelte works by compiling code at build time, not runtime. It means that (in a sense) you get the best of both worlds – Svelte compiles our code into static markup where possible at build time while still allowing those elements that need to remain dynamic to operate. In most cases, this will be enough; given that we don’t need to use a runtime library like React, this should lead to a pretty fast site! There is something to be aware of, though – it’s possible to create and use client-side components if you decide to work server side with Svelte. It does require changes to how you factor your code; working in a server-side environment will help give better SEO (we can compile more on the server, compared to client side). The downside is that any changes made will force a re-render on the server, which can get expensive in terms of resources. Nevertheless, it’s something to think about – if your site isn’t that technically complex, you might get better performance working client side!

If you would like to delve into the world of server-side rendering with Svelte, then take a look at these two articles as a starting point. One is by Nathan Kessler at www.base2.io/2020/12/12/svelte-­ssr, and the second is the main API docs for SSR and Svelte, at https://svelte.dev/docs#Server-­side_ component_API. Okay, let’s move on. It’s time we got stuck back into our demo front end, methinks! So, over the following few pages, we will turn our attention to incorporating an external library into our demo front-end site. There are dozens we might want to use, but I have the perfect task for us: why not incorporate a payment processor feature into our website?

Adding a Payment Processor Yes, the sharp-eyed among you will have spotted that we’ve built everything else but not provided a way to pay for our goods. In the hope that we wouldn’t want to give things away for free, we need a way to pay for goods. Adding a payment processor is where things get interesting: there are 242

Chapter 10

Working with External Libraries

dozens of different tools we might use, but, surprisingly, there seems to be a shortage of documentation available on how to incorporate them into Svelte. Huh? I hear you ask, surely we don’t need anything, right? Wrong – this is one occasion where it pays to have the proper documentation! If we didn’t, there is every possibility we might miss something, and that could mean the difference between accepting and rejecting a card. Not a good start, particularly if we reject what might be a perfectly valid card. But I digress. Fortunately, there is one payment provider that has created a library to support Svelte: it’s our good friend, PayPal. In some respects, this is a good choice: we have a small site, and PayPal makes it supereasy to start on something small. Yes, we could go to the extremes of setting up catalogs in tools such as Shopify or Stripe, but for a small site, this is overkill! So instead, using a tool such as PayPal means we can get set up quickly; if we start adding more products, we can then consider moving up the scale to tools such as Shopify. Okay, enough chitchat. Let’s crack on with our demo. We will get to coding momentarily, but we do need to complete some basic housekeeping admin first. I know it’s not everyone’s favorite topic, but we would have to do the same for any payment provider, so let’s get it out of the way before moving onto the fun stuff.

Getting Prepared Before we get started, please make sure you have signed up for a personal account with PayPal or can use one you already have. PayPal comes with a sandbox option for developers; it’s this option we will use through the rest of this chapter. We will not submit any actual orders or charge anything to your account; everything will happen in a sandbox environment, away from any real account settings.

You may need to set any settings for your own country to satisfy PayPal’s security requirements; please adapt any steps where needed for your country.

243

Chapter 10

Working with External Libraries

DEMO – PAYPAL HOUSEKEEPING Assuming you have access to a PayPal account, follow these steps to get the details we need for integrating into our demo: 1. Once complete, we need to get our API credentials, so we can begin to use PayPal – log into your developer dashboard at https://developer. paypal.com/home, and then under Dashboard, click My Apps & Credentials. 2. Make sure you select the Sandbox tab at this point – this is important: it will show the proper credentials to use in a test environment. 3. Click Default Application under the App Name column – PayPal will create a new developer dashboard account for you. 4. Next, take a copy of the long Client ID value, and save it for safekeeping – we will use it in the following two exercises.

You will also see a sandbox account email address – this isn’t a real one! It’s there to act as the recipient’s email address when receiving orders. 5. Once copied, head over to https://developer.paypal.com/developer/ creditCardGenerator/. Go ahead and choose your country, and then note the details provided; this we can use to test our integration later in the following two demos. Excellent, we now have the details we need for the next part of our demo. I know it might seem a bit of a mixed bag of steps, but it will all become clear as we move to use the values in our demo. At this point, we could skip ahead and try to incorporate the PayPal code directly into our site. However, we won’t have the opportunity to see how it runs; if it doesn’t go according to plan, we may make changes to our site that are unnecessary. To reduce the risk of that happening, let’s run the code as a stand-alone demo first to get a feel for how it works before making changes to our front-end demo.

244

Chapter 10

Working with External Libraries

Taking a First Look at the PayPal Demo The payment stage is the most critical part of our site – yes, we need pages with information about our products, but we’re not going to give anything away for free, no matter what state those pages are! Before we go hammer and tongs to change our demo, let’s quickly run the vanilla example provided by PayPal to get a feel for how it works. As it so happens, we will need to make a small change to get it to work.

I will assume you install to the root of C: for convenience – please adjust if you wish to use a different area.

RUNNING THE SVELTE DEMO To try out the initial PayPal demo for Svelte, work through these steps: 1. First, browse to https://github.com/paypal-­examples/svelte-­ paypal-­js – go ahead and click the Code button toward the top right and then Download Zip to download the demo. 2. Go ahead and open the archive file you’ve just downloaded, and then extract the contents and save to the root of your C: drive. Rename the extracted folder to svelte-integration.

The rename option isn’t obligatory – it’s just to make it easier to reference in the next step. 3. Go ahead and open Checkout.svelte from the \src folder, and then look for const CLIENT_ID = 'your-client-id'. Change the 'your-client-­ id' text to the ID you saved in step 4 of the previous exercise. Save and close the file. 4. Fire up a Node.js terminal session, and then change the working folder to the svelte-integration folder. 245

Chapter 10

Working with External Libraries

At this point, we would typically run npm install to download dependencies, but if we do, you may hit a small error in the code! It’s irritating but easily fixed and relates to a slightly out-of-date package – let’s fix it before continuing with the remaining steps. 5. Switch to your text editor, then crack open package.json, and look for this line: "rollup-plugin-css-only": "^3.0.0",

6. Change the value to this: "^3.1.0". The newer version of this package fixes the issue. 7. With the updated package in place, switch to a Node.js terminal session, and make sure the working folder is pointing to our project area. At the prompt, enter npm install to download and install all of the dependencies for this test. 8. The install will take a few minutes – once complete, enter npm run dev at the prompt. 9. If all is well, we should see the screenshot shown in Figure 10-4. Go ahead and click Debit or Credit Card at the foot of the demo.

Figure 10-4.  The starting screen for the PayPal demo 10. Fill out the details shown in the form that appears – make sure you enter something in every field where it doesn’t show the word Optional! 11. Once filled out, leave the Deliver to billing address field ticked, and then click Buy Now.

246

Chapter 10

Working with External Libraries

12. You will see a spinner kick in while the browser sends the data to PayPal – if all is well, we should see the response shown in Figure 10-5.

Figure 10-5.  Confirming that the initial PayPal demo works as expected Yes, that’s a relief: we have something that works! But, while it is a big step forward, it does raise some questions about what we might do if we wanted to upgrade to a payment provider that offered more features. But – as they say – that’s for another day: instead, now that we’ve seen it working, let’s crack on and get PayPal integrated into our site.

Adding PayPal to Our Front-End Site Okay, it’s time to bite that bullet and add PayPal to our site! Although this might seem a little scary, don’t worry, PayPal has done most of the hard work for us already. We simply need to drop in the extra component and wire it up as part of our existing Cart component. That said, we will still have a few steps to work through – let’s get to it and see what is involved in more detail in the first part, where we add the PayPal code to our site.

247

Chapter 10

Working with External Libraries

DEMO – ADDING PAYPAL To add PayPal to our site, follow these steps: 1. First, we need to install the PayPal library – for this, fire up a Node.js terminal, and change the working folder to our project area. 2. At the prompt, enter npm install @paypal/paypal-js --save and press Enter. 3. In the meantime, switch to your text editor – we need to create a component that will consume the PayPal library. Fortunately, PayPal already has a perfect component for this purpose – let’s add it in block by block, starting with some declarations:

249

Chapter 10

Working with External Libraries

9. This last step is to add in a tweak for styling, to make sure that the PayPal button container is suitably positioned on-screen:

10. Save the component as Checkout.svelte, at the root of the \src\component folder. 11. We have a couple more steps to do – the first is to add a reference to the Checkout component at the head of the Cart.svelte file. Crack that file open, and then amend the code as highlighted:

7. Press Ctrl+S (or Cmd+S) to save the code, and then hit the Refresh button next to the URL in the tab on the right – if all is well, we should see a new button appear (Figure 10-9).

Figure 10-9.  A React button in a Svelte application And voilà, we have a working React component running inside a Svelte application! Granted, it was a simple React component and probably not using techniques that reflect current development practices, but – it’s a React component. I’m sure we could refactor the code to make it more reusable (such as moving the React component into a separate file). Still, it illustrates how we might consume existing React components in the interim until native replacements can be sourced or written in Svelte. In the meantime, this technique exposes a couple of valuable points, so without further ado, let’s take a closer look at how the demo works in more detail.

257

Chapter 10

Working with External Libraries

Breaking Apart the Changes Combining React and Svelte seems like a bit of a paradox! After all, both operate differently (although there are some similarities, at least in code). Nevertheless, it can be helpful on occasion to consume existing React components in Svelte code, particularly if we’re migrating from the former to the latter. To achieve this, we first imported three functions – onMount() for Svelte and the two React libraries for React. We then created our React component – in this instance, I kept it simple by using React.createElement to create a LikeButton, but we could have chosen to build something more complex. We’ve defined the initial state inside this component and then rendered the LikeButton and its onClick event handler, along with some basic styling. I know the styling isn’t great, but the key is the import, not how we make it look aesthetically pleasing! For the last step, we used Svelte’s onMount() to render the ReactDOM object that contains the instance of our LikeButton, which we display on the screen in the specified container. You can see a demo of this import in a CodeSandbox I’ve created at https:// codesandbox.io/s/importing-­react-­components-­into-­svelte-­1nhgi.

While researching for this book, I came across an interesting article by Chris Coyier on understanding the differences between React and Svelte and how one can refactor code from React to Svelte to cover most circumstances very quickly. The article is at https://css-­tricks.com/svelte-­for-­the-­experienced-­ react-­dev/ – it’s worth a read, particularly if you’re moving from React to Svelte!

S  ummary Although Svelte is a potent tool in its own right, it can’t do everything – there will come a time when we need to import a third-party library of some description into our project. Fortunately for us, there are several ways to achieve this, although the final answer will depend on our requirements. Throughout this chapter, we’ve explored those options in greater detail – let’s take a moment to review what we covered in more detail. We kicked off first with a look at the different ways we can import content into Svelte, from simply linking to files in the final build through using the likes of svelte:head to 258

Chapter 10

Working with External Libraries

creating reusable actions that we can call from any location in our projects. We then used the examples to create demos to explore how they work and begin to understand some of the differences that might influence which option we would use for our requirements. Next up, we covered off an essential point around working server side and that this will affect how we import libraries. At the same time, we explored how Svelte is different from other libraries, and for the main, we learned that working client side will suit most needs when working with Svelte. We then moved onto adding a payment processor to our project – we used PayPal, as it was simple to set up (which suits the small size and ethos of the site). We first did a dry run-through of a demo designed for Svelte before adding the changes to our site and finally testing the result works as expected in our browser. We then rounded out the chapter by answering a question – Rich Harris, the original creator of Svelte, claims that you can import components from other frameworks such as React into a Svelte application. We learned that it is indeed the case, and while it may not look as pretty, it can undoubtedly help migrate to using Svelte! Okay, we’ve come to the end of this chapter, but don’t worry, we have more to cover! It’s time to get animated and see how we can add that extra special touch to our front-­ end design… to give it that sparkle, so to speak. Hopefully, by now, you might have an idea of where I’m heading with this: stay with me, and I will reveal it all in the next chapter.

259

CHAPTER 11

Animating Svelte Until now, we’ve covered the core elements of Svelte as part of building our site – it’s time to add a little extra sparkle! We could do this in one of several ways, but a great example is an animation. Fortunately, Svelte makes it easy to add any effect we desire; the trick is to make sure we don’t overdo the effects. In this chapter, we’ll examine how Svelte supports animating, transitioning, and tweening, plus add in some custom effects to our store front-end project. We’ll start first, though, with a question: what could (or should) we add to our site?

A  uditing the Site Adding any form of animation to a site – be it a transition, animation, a tween, or similar – can be a double-edged sword. Do it well, and it looks fabulous; anything else will make the site look tacky and damage the reputation of the owning company. Take, for example, this site – www.fournier-pere-fils.com/. I first wrote about their site when researching for one of my other books, Practical SVG. The site had a fantastic picture of a vineyard with the occasional bird flying over and the sun shimmering through the trees. It might have taken a moment or two to load, but it was worth the wait! How does that fit in here, I hear you ask? Well, in answer, on two counts: the site is advertising upmarket wine, so the animation adds a touch of class, and secondly – most importantly – it doesn’t overdo the effects! Fast forward to now, and the site still runs an animation, but this time of their cellar, you can see the sun shining through the windows and slight effects of dust. It creates a really atmospheric view of something meant to be aged but, at the same time, is not overdone.

© Alex Libby 2022 A. Libby, Practical Svelte, https://doi.org/10.1007/978-1-4842-7374-6_11

261

Chapter 11

Animating Svelte

Okay, back to reality. Although our site is minimal, it doesn’t mean we can’t add anything; there are a few ideas that come to mind. Here are a few to start us off: •

Adding media such as video – granted, it’s not an animation in the true sense, but providing something has become an almost de facto standard!



How about an image carousel? I’ve seen dozens of different sites use a carousel of some description, particularly those selling coffee.



We’ve added add-to-cart buttons in our demo, but they lack any notification when clicked – how about adding something to tell the user that the chosen product is now in the cart?



Remember that offer modal we set up on our home page, advertising the discount? We can refine it further by animating when it appears or is closed to provide a smoother transition.



This last idea is perfect for mobile devices – what about adding a hamburger menu? It’s excellent for holding menu items in a confined location which is what we have here – we can animate the opening and closing to provide a smooth effect for our customers.

I’m sure you can think of more instances where our site could benefit from some form of animation or transition – hopefully, this handful of examples will give you an idea of what is possible! The actual proof, though, is in the pudding (to badly quote an English saying). We can only experience it when we add it to our site and see it in the flesh. With that in mind, let’s start with a demo. Don’t worry too much about how it all works; it’s more to show how easy it is to add animation in Svelte.

L earning a Language Okay, I thought this was a book on using Svelte, so why are we talking about learning a language, I hear you ask? Have no fear, my dear readers – I have not lost the plot! Let me explain. While researching this book, I was toying with ideas around how I could illustrate Svelte’s animation and transition effects before adding it into our front-end project. I had a few ideas come to mind and was quite happily working through them until I came across this: https://svelte.dev/repl/b68344fe6d0b413494905b41c25a0a3f?version=3.29.0. 262

Chapter 11

Animating Svelte

Mamma mia, I yelled – this is perfect! And why? Well, it is a port/clone of an app that I happen to have been using for some time. That app? Duolingo. Yes, for some time now, I’ve been using it to learn Dutch. Okay, yes, I know – it might seem crazy since I hail from the UK, but, hey, I’ve always loved speaking a different language, and I thought why not: Dutch isn’t the easiest, but I enjoy a challenge! For those of you who are not familiar with it, it’s an excellent app for learning a new language – it allows you to set a certain amount of time each day to learn in simple, quick exercises. The basic principle is that you drag and drop words (in this case, Dutch) from a selection at the bottom into the correct order to match a phrase in your local language. It’s perfect to illustrate how Svelte uses animation, transition, and easing effects, so without further ado, let’s dive in and take a look at how in more detail.

DEMO – USING ANIMATE AND TRANSITION IN SVELTE To set up our demo, follow these steps: 1. First, go ahead and browse to www.svelte.dev/repl – don’t forget that the URL will redirect to show the version of Svelte in use! 2. We have a fair bit of code to add, so we’ll start with the script block – go ahead and add in this code to App.svelte on the left, which takes care of defining some initial imports and the crossfade animation:

value: value: value: value: value: value: value: value:

"Ik" }, "graag" }, "Svelte" }, "gebruik" }, "echt" }, "is" }, "het" }, "gaaf" },

4. With the script in place, we can now focus on the markup. The first part will take care of what we drag and drop into the final answer – go ahead and add this markup, leaving a line blank first:

       {#each selected as word (word.value)}        {           word.selected = false;           selected = selected.filter(w => w.value !== word.value)         }}>         {word.value}       

264

Chapter 11

Animating Svelte

    {/each}   

5. We still need to add the markup for the origin, that is, where the words are dragged from. For this, skip a line after the previous block, and then add in this code:        {#each words.filter(w => !w.selected) as word (word.value)}        {           word.selected = true;           selected = [...selected, word];         }}>{word.value}     {/each}   

6. We’re almost done – we need to add in the last stage, which is styling! Fortunately, it isn’t too substantial – skip a line after the code for the previous step, and then add in these rules:

Note – for space reasons, I’ve compressed the styles; they are displayed properly in the code download, so feel free to copy and paste from there. 7. We should see something akin to Figure 11-1 appear on the right if all is well. Here, I’ve already moved some of the words across into the destination.

Figure 11-1.  Choosing words in the Duolingo clone

266

Chapter 11

Animating Svelte

Phew, that might seem like a lot of code, but in reality, much of it is standard markup and CSS styling! That said, it highlights a few key points we should explore in more detail ahead of updating our front-end demo. Let’s dive in and review the code in more detail to see why Svelte is so powerful in animating content.

Oh, and that phrase? It’s “I love Svelte, it is really cool!” in Dutch. 😊

Understanding How the Code Works I’ve always loved learning a new language from an early age – over the years, I’ve spent time learning French, Latin, Spanish, and, more recently, Dutch. Dutch isn’t the easiest to pronounce, so using the Duolingo app is a great help – when I came across an anonymous demo that replicated the effect, I just had to include it. This demo is a perfect way to show off all three critical examples of animating content in Svelte – it includes animation, transition, and easing effects at the same time. We first import examples of each from within Svelte (so we avoid the need for thirdparty libraries) before creating a send/receive function. This function calculates which item is sent from the source list and where it lands in the destination list. It then works out and returns an object that contains all of the CSS style properties of each word being sent or received. We apply a quintOut easing effect and transform, scale, and opacity CSS properties as part of this function. Next up comes the words object, into which we specify a mix of Dutch words that will act as the source for our demo. At the same time, we also create an empty selected array – this will be the target for each word we drag over when running the demo. We then move onto the HTML markup – we start with the destination block, into which we drag words. For #each word we send over, we create a span that stores each word as it is pulled in or out (we can send back words if we get them in the wrong order). We apply a few properties such as animate:flip, a class of word, and set the in: and out: properties to determine the word order. In the next block of HTML markup, we do something similar, but this time for the origin block and for words that we select – this is our source for all of the words we can choose from in our demo.

267

Chapter 11

Animating Svelte

The flip animation in Svelte is a little unique – it stands for “First, Last, Invert, Play” and is ideal for reordering animated elements, particularly if they move from one list to another.

Reviewing the Types of Animation Options If you mentioned the word animation, you would be forgiven for thinking that it might require the services of a third-party library, right? Or oodles of CSS throughout our code… What if I said that wasn’t necessary? Not so with Svelte – the framework comes with great support for animations, transitions, and motion features, already built-in! Sure, we can use CSS animation with Svelte or just plain JavaScript, but that isn’t always necessary – we can already achieve quite a bit with tools baked into the framework. To see what I mean, let’s take a quick look at what Svelte has to offer when it comes to animations or transitions. Broadly speaking, animations created using Svelte can fall into one of three categories, based on a central premise – is that element being added to or taken away from the DOM? Take animations, for example – in this instance, elements won’t be static but are not transitioning out of the DOM. Here, we use the animate directive. For elements that transition in and out of the DOM and behave differently, we use the transition directive. If we want to control the speed at which these happen or the effect of the transition, then we can use the motion directive or apply an easing effect to the animated element. We can see the differences between each in Table 11-1.

Table 11-1.  Different types of animation supported by Svelte Type of animation

Purpose

Animations

Add the illusion of motion to elements that are not transitioning in or out of the DOM

Transitions

Works the same as animations but used for elements that are added to or removed from the DOM

Motion

Two effects: tween, used to control the speed and appearance of the animation (using easing, etc.); spring does a similar effect but is suited more for constantly changing elements, such as playing online games or using an online drawing app

268

Chapter 11

Animating Svelte

I use the term “animated element” to describe elements animated with Svelte and where we apply some form of effect to that element. Okay, let’s crack on. I want to cover one more animation effect, which is easing. Strictly speaking, it’s not an animation by itself, but more of a way to control the effect of animations or transitions. We can use easings to create some funky effects with a bit of math – I will come back to that shortly, but for now, let’s look at how we might apply common easing effects to a Svelte animation or transition.

Applying Easing Effects Take a look back at the code in the Using animate and transition in Svelte demo near the start of this chapter – notice how in addition to using animate and transition, we also included an easing attribute? As with any other library or framework that supports animation, we use easings to control the speed of animation to make it feel more natural. Real objects don’t all move at a consistent rate and, likewise, won’t stop or start in the same way – we can use easings to replicate the same effect in our code. We use JavaScript or CSS to create easing effects. However, it’s worth noting that if you want to create more complex effects such as Bezier curves, then you will need to use CSS for this – Svelte doesn’t yet support creating them natively, and you will get better performance using CSS! The best way to see how this all works is to dive into some code – over the following few pages, we will create two demos using Svelte. The first will cover how we can add custom easings using JavaScript, while the second will apply easings using CSS.

Creating Custom Easing Effects in JavaScript For this demo, we will use a copy of the code from the deferred transitions demo – Svelte already has good support built-in for easings, but we will add our own using the easings provided in a Gist from Gaetan Renaudeau at https://gist.github.com/gre/1650294. They have been around for some time but still work perfectly fine for our needs – creating a custom easing can be a complex matter sometimes, so anything we can do to keep things simple will be better for all! 269

Chapter 11

Animating Svelte

CUSTOM EASING USING JAVASCRIPT To add a custom easing, follow these steps: 1. From the code download that accompanies this book, extract a copy of the code for the deferred transitions demo.

Alternatively, you can copy the code from the same tab in the original demo at https://svelte.dev/tutorial/deferred-transitions. 2. Go ahead and browse to www.svelte.dev/repl, to create a new REPL; paste the code into the App.svelte tab on the left. 3. The first change to make is to remove the line starting with import { quintOut }... from just below the opening

279

Chapter 11

Animating Svelte

5. We need to add one more change, which is to drop in this call to the NotificationDisplay component, immediately above the call to CTAButton:

addToCart(product)}>

6. Go ahead and save the file, and then close it. We need to make similar changes to Product.svelte, so go ahead and open that file in your editor. 7. As before, we need to add the import statement: import { Link } from "svelte-routing"; import { NotificationDisplay, notifier } from '@beyonk/sveltenotifications';

8. Next, add in the call to the Notification component, as we did back in step 4:   $cart = [...$cart, product]   notifier.danger('Product added!', 7000) }

9. We also need to call the component, so add in this line (highlighted):

addToCart(product)}>   Add to cart

10. Save the changes, and then switch to a Node.js terminal session. 11. Make sure the working folder is set to our project area, and then at the prompt, enter npm run dev and hit Enter. 12. Try browsing to http://localhost:5000/products and then clicking Add to cart against a product; if all is well, we should see a notification appear top right, as indicated in Figure 11-4.

280

Chapter 11

Animating Svelte

Figure 11-4.  A notification to confirm we have added a product to the basket There, that’s better! We can at least tell our customers that they can be assured it will be added to the basket if they add a product. It’s a simple addition, but the key to maintaining a good experience for our customers. We’ve not added any directly in our code, but the component itself uses some great examples of animation; let’s spend a moment or two to review the code in more detail to see how it uses Svelte animations.

Understanding the Changes Made Notifying customers of an action that has taken place is essential to maintain a good customer experience. After all, customers will lose faith if they can’t tell if something has happened! In this last demo, we took the opportunity to improve the existing add-to-cart buttons by adding a notification once we add a product to the basket. To do this, we first installed the Svelte-Notifications plugin before adding an import for this plugin to the Products.svelte page. Next up, we then added a reference to trigger the notifier event, along with relevant text and a timeout period of 7000 (or 7 seconds). We then bound it to the CTAButton component using NotificationDisplay. We then repeated the same exercise, but in the Product.svelte page – once added, we ran up the Svelte dev server to ensure the notification triggered as soon as we click the add-to-cart buttons on each page. Excellent – let’s crack on. We’ll stay with the animation theme, but this time crank it up to something a little more obvious! How many sites have you visited where you see some form of animated banner or carousel appear? Some developers claim it’s not so good for things such as SEO, but I’m not so sure – it’s perfect for adding a little visual interest and providing a link directly to a product or content. Leaving aside any thoughts on topics such as SEO for now, let’s look at how we might add such a component to our site in more detail.

281

Chapter 11

Animating Svelte

Iterating Through Pictures In our next demo, we’re going to step things up a little and add something I am sure you will have seen on dozens of websites: a carousel! Over the years, I’ve seen thousands of them in various guises, although they do get something of a mixed press. I’m not entirely sure why, as I think it’s a great way to maintain a dynamic, eye-catching element to a page and provide a little visual interest. Whatever your thoughts on them, it’s a valuable tool to add – there is one question, though: which one do we use? Deciding which to use takes a little research, as many provide features that you might not need or be overkill for your site. It’s worth researching to see what is available: for our next exercise, I will use one created by Jio Scon, available from https://github.com/jioscon/svelte-image-carousel-slider. Okay, it may not be as feature laden as others, but that doesn’t matter: it’s more about how we animate that is important here! With that in mind, let’s dive in and take a look at what’s needed to set up our carousel in more detail.

DEMO 3: IMAGE CAROUSEL For this exercise, you will need five images of a suitable size – I’ve used 640px by 427px to get a decent balance between displaying content and not taking over the whole home page.

If you don’t have any images, then try a site such as Pexels.com (www.pexels. com) – their small image size happens to match the dimensions I’ve used! You need to use the horizontal ones, though, as vertical images won’t work so well on our site. Once you have these, then follow these steps: 1. First, go ahead and download a copy of Carousel.svelte from the code download that comes with this book – save it into the \src\components folder. 2. Next, we need to import this into the home page – for this, open Home.svelte, then scroll down to this block, and comment out all three lines:

282

Chapter 11

Animating Svelte

  

3. Add in this line immediately below:

4. Next, scroll to the .welcome class rule in the style block, and add in this extra property: margin-bottom: 20px;

5. Save the file and close it. Next, switch to Modal.svelte – we need to make a change to the .modal class specified in the style block. Scroll down to that rule, and then add this attribute at the end:   z-index: 10; }

6. Go ahead and save all files, and then close them – once done, revert to a Node. js session, and then make sure the working folder is our project area. 7. At the prompt, enter npm run dev, and then switch to a browser – if we browse to http://localhost:5000, we should see a carousel appear once we clear the modal dialog (Figure 11-5).

283

Chapter 11

Animating Svelte

Figure 11-5.  The completed carousel on the home page (image source: pexels.com) Adding a carousel to our site provides a nice visual touch; it is true that a thousand pictures say more than words! We’ve not added links in our instance, but this wouldn’t be hard to do; customers can then click through to specific pages on our site, rather than navigate manually. This particular carousel shows off some useful features, including one crucial point, so let’s take a moment to review the code in more detail.

Understanding What Happened Adding visual interest to any site is essential in today’s Internet – long gone are the days of black text on gray backgrounds, reminiscent of late 1990s’ web styling! (Anyone remembers that? We’ve come a long way since.)

284

Chapter 11

Animating Svelte

One way to add in that visual content is through the use of a carousel – in the last exercise we’ve just completed, we used the Image Carousel Slider plugin by Jio Scon to add content on our home page. We began by installing the plugin using the typical npm install command before adding an import for the plugin and commenting out the original static banner image in Home.svelte. We then added a call to the plugin before switching to Modal.svelte to tweak the z-index property for the modal - the latter was getting in the way of our carousel and producing some interesting effects! Once saved, we could then run up our demo and test it to ensure it animates the content as expected on our home page.

For another example of a similar component for Svelte, but with a few more features, try Svelte Carousel, available from https://vadimkorr.github.io/ svelte-carousel/.

S  ummary Phew, that has certainly been something of an animated adventure if you pardon the (terrible) pun! Animating content in Svelte can be something of a minefield, depending on how you apply it – keep in mind that it should supplement our code and not become a dependency. That said, we’ve covered a lot of content over this chapter, so let’s take a moment to review what we have learned. We kicked off with a quick audit of our front-end site to see what animations we could add and maintain a refined look to the content. We then ran a demo to explore some of the types of animation we might use before going into more detail on the different types available within Svelte. Next up, we then explored how to add in easing effects before looking at creating ones in both CSS and JavaScript. At the same time, we learned that using the same effect created in both CSS and JavaScript isn’t ideal, as there are differences in how we handle them in Svelte. We then took a look at some example third-party libraries; we understood that while Svelte offers excellent support for animation and that help isn’t often needed, we can still use these libraries if required.

285

Chapter 11

Animating Svelte

We then rounded out the chapter by adding some effects to our front-end demo – we started by updating the discount banner before moving onto adding a notification on the add-to-basket buttons and adding in a carousel effect on the home page. Okay, we are almost at the end of our project, but I have one more topic to cover. We’ve created all of our code from the ground up, albeit with some help from thirdparty plugins. Creating something from the ground up is perfectly acceptable, but a lot of work! What if we could have some of this already done for us? Stay with me, and I will reveal all in the final chapter.

286

CHAPTER 12

Adapting for Sapper We’ve almost reached the end of the book, but we can’t finish without touching on one essential part of using Svelte – some of the third-party libraries based on the framework. I’m thinking particularly of Sapper; it’s a great framework built on Svelte and wraps many essential functions into one friendly, easy-to-install site generator tool. Throughout this chapter, we will look at how we can use it to create a new site; we’ll work through some of the differences and see how it can assist with some of the tasks we’ve had to complete manually. At the same time, we’ll explore its upcoming replacement, SvelteKit. But first, I must start with a confession.

I ntroducing... Sapper? This chapter was meant to be about Sapper, the app framework for generating Svelte sites. Sapper is a valuable tool in its own right, but as can happen, plans change: it doesn’t reflect what we expect to see in today’s world. There are a couple of shortcomings with the tool: •

The codebase dates from 2017 and has become a little unkempt – it was built for an age where server technology was a consideration, and things have changed dramatically since.



The codebase differs from standard Svelte, so making it more complex and less predictable when writing code.



There is a rising trend toward unbundling code and serving it as modules instead; it means the startup process is almost immediate, irrespective of size.

So, on that basis, sorry to disappoint if you were expecting to see Sapper; it makes much better sense to look forward to what is coming, in the form of Sapper’s replacement, SvelteKit! With that in mind, the chapter will be about converting to use © Alex Libby 2022 A. Libby, Practical Svelte, https://doi.org/10.1007/978-1-4842-7374-6_12

287

Chapter 12

Adapting for Sapper

SvelteKit; this is a more straightforward process as much of the code can be lifted and shifted as is, with only minor changes needed. Now that we have that out of the way, let’s crack on. Much of this chapter will be about converting our existing front-end site to use SvelteKit. We’ll go through each part of the site to point out the changes we need to make; we’ll finish with a quick look at how we can take things forward once the primary site is in place. We’ll start first with a short exercise to learn how to create an initial SvelteKit site.

Migrating Our Project – Setting Expectations Before we get started on coding, though, there is a little housekeeping admin we need to cover first – yes, I know, it’s not everyone’s favorite thing, but it’s a necessary evil! Nevertheless, there are a few things we should be aware of for this particular chapter:

288



SvelteKit is beta software, so do expect things won’t work entirely or that we might come across bugs. That said, the framework is still pretty stable – while you may want to hold off pushing content into production for the moment (at least until it hits version 1.0), it’s still worth playing with the framework, ready for when you can deploy your finished site.



Most of the code you need for this chapter already exists in the sveltebook demo we created in previous chapters – I would recommend taking a copy of that site and using it as your source for this chapter.



I will assume you are working on Windows, that the name of our project folder is sveltekit, and that it’s located at the root of C: drive. Any time you see the words “project area,” then assume it is this folder. I will refer to the original site we created using Svelte, so you may want to read through the steps first to ensure you know which folder is which!



If you use macOS, Linux, or prefer to use a different folder or drive, please adapt accordingly.

Chapter 12

Adapting for Sapper



As far as tools are concerned, we don’t need anything new – as long as you still have Internet access and your text editor, then this will be fine.



For space reasons, we’ll focus on the key changes to get the replacement SvelteKit site working; I will run through what’s left to do as the next steps toward the end of the chapter.

Okay, with the housekeeping done, we can now really get started! Throughout this chapter, I will take you through a multipart demo that covers the steps required to get our SvelteKit replacement site up and running. Let’s begin with creating the initial site.

Setting Up the Initial Site The first step in our conversion project is to create an initial site – although SvelteKit was built for Svelte, there are a few changes that we need to make. It’s much easier to do these from the ground up than to convert an existing site! With that in mind, let’s start with our first exercise, creating a SvelteKit site.

ADAPTING OUR SITE – PART 1: CREATING THE BASE To set up an initial SvelteKit site, follow these steps: 1. We first need to make sure we have Node 14.17.x or above – for this, fire up a Node.js terminal session, and then at the prompt, enter node -v and press Enter. 2. If the response back says a number lower than 14.17.x, you will need to update Node.js for your platform. The easiest way is to head over to www.nodejs.org, and then download and install the executable or package for your platform. If you have Node 14.17 or above, then please skip to step 3. 3. Assuming you have Node 14.17.x or above installed, change the working folder to be C: 4. At the prompt, enter this command and press Enter: npm init svelte@next sveltekit

289

Chapter 12

Adapting for Sapper

5. You will be prompted for several bits of information during the initial install – choose the highlighted options as indicated: Which Svelte app template? » Skeleton project Use TypeScript? ... No Add ESLint for code linting? ... Yes Add Prettier for code formatting? ... Yes

I’ve chosen not to use Typescript as a matter of preference; please feel free to select Yes for that option if you prefer, but please note that the code examples in this book are written for standard JavaScript, not Typescript. 6. Once completed, change the working folder to our project area, and enter this command at the prompt: npm install

7. Node will install all of the dependencies required; when prompted, please enter npm run dev and press Enter at the prompt. 8. Next, go ahead and browse to http://localhost:3000 – if all is well, we should see an initial site displayed, as shown in Figure 12-1.

Figure 12-1.  The initial SvelteKit site

290

Chapter 12

Adapting for Sapper

Excellent – we have our initial SvelteKit site in place! It might require a little more work than a standard Svelte site, but bear in mind that it includes a few more features not present in a Svelte application. Let’s take a moment to review the steps in more detail before we move on to exploring our new site’s file and folder structure.

Exploring the Code in Detail Setting up a SvelteKit site is very easy – hopefully, you will have noticed that the process is similar to that we used for a standard Svelte site. Nevertheless, we need to discuss a couple of essential points – let’s take a closer look at the code we used in this demo. The first important point is the version of Node.js we used – this is where you may come unstuck if you don’t have the correct version installed! The official documentation says we should use Node.js version 12 or above, but I’ve seen anecdotal evidence that says even this version doesn’t work correctly! At the time of writing, I used version 14.17.3, which works fine; as long as you use this or newer, you should be OK.

If you try to use version 12, you will likely get this error: SyntaxError: Cannot use import statement outside a module. SvelteKit uses modules everywhere, which Node 12 supports, but it seems those in SvelteKit don’t work unless we use Node 14 or above. We then ran the standard command to install a new SvelteKit site – as this bundles a few packages, it prompted us for a few details. The responses we’ve used are a matter of preference; you may prefer to use different ones for your projects. The final step for this demo was to run the npm install command – this installs all of the required dependencies for our project. We then started the SvelteKit development server and browsed to our initial site to verify all is working as expected in the browser. Okay, let’s move on. Now that we have a base site in place, it’s worth taking a moment to review the file and folder structure for a typical SvelteKit site. If we were to compare it against a standard Svelte site, we would see some similarities; there are some differences though that we should be aware of, so let’s dive in and take a closer look.

291

Chapter 12

Adapting for Sapper

Understanding the Structure of a SvelteKit Site Cast your mind back to when we created our initial Svelte site – yes, all the way back to Chapter 1, if you can remember that far back! Remember what the initial folder structure looked like once we had created the foundation site for our project? The folder structure for SvelteKit is very similar – you will have the requisite package files, plus the \src folder as before. However, there are a few changes compared to a standard Svelte site, both in file names and structure – we can see them listed in Table 12-1.

Table 12-1.  A list of critical files and folders in a SvelteKit site, with their purpose File or folder name

Purpose

node_modules

This folder is standard for any Node-based website

src

The main source folder – inside this, you will see (by default): app.html global.d.ts In this folder, we will add any content that we need to compile during the build process, such as layouts, pages, and components

static

Reserved for any content, media, or artifacts that we do not need to compile, such as style sheets, fonts, and images

.eslintrc.cjs

Used to configure ESLinting, which can be enabled if desired when creating a SvelteKit site

.gitignore

A standard file for holding exclusions that we should not merge into a Git repository

.npmrc .prettierignore .prettierrc

Various configuration files (not specific to SvelteKit) for controlling properties

jsconfig.json

Configuration properties for compiling SvelteKit sites

(continued)

292

Chapter 12

Adapting for Sapper

Table 12-1.  (continued) File or folder name

Purpose

package-­lock. json package.json README.md

Standard files for a Node.js/Git website

svelte.config.js

A configuration file for controlling whether Google’s FLoC targeted advertising technology is enabled. It is disabled by default, as it is deemed harmful by the Electronic Frontier Foundation. Most browsers (except Google) do not implement the technology

It is helpful to understand the file structure theory, but there is no substitute for getting stuck into code! The best way to get familiar with the structure is to start using the site; with that in mind, let's update the layout template that comes with each SvelteKit site.

Updating the Layout Right, where do we start? Well, things will be a little different for us – whereas before we were using App. svelte as a makeshift template, SvelteKit introduces the concept of templates proper; we can use this to build up the header, footer, and general layout of the page. We can use the element – this tells Svelte to add any content in pages or components into this bucket to display the compiled page on the screen. The vital thing to note, though, is that layout filenames in SvelteKit start with a double underscore – it makes a private file, so it’s not visible to end users but can still be used to create the finished pages. Let’s take a look at how to set up the layout file in more detail.

293

Chapter 12

Adapting for Sapper

ADAPTING OUR SITE – PART 2: ADDING THE LAYOUT TEMPLATE To update the layout for our new site, follow these steps: 1. First, go ahead and extract a copy of __layout.js from the code download that accompanies this book – save it to \src\routes in our new project folder. 2. Next, copy across the Header.svelte and Footer.svelte files from the \src\components folder in our original project folder, and drop them into a new \components folder under \src in the new project area. 3. We also need to bring across a copy of stores.js and stock.json from the \src folder of our original project – save these to the \src folder in our new project area. 4. We need to bring two more folders – copy the fonts and images folder from within the \public folder in our old site to the \static folder in the new project area. 5. Switch to your text editor, and then crack open a copy of the Header.svelte file – we are going to comment out the context part for now. It’s not essential to getting the site operational; we can always come back to it. Comment out lines 18–20, then 65–67, and 69 – it will show as if we are a Guest login, but that’s OK for now! 6. Next, revert to a Node.js terminal session, and then make sure the working folder points to our new project area. 7. At the prompt, enter npm install svelte-inline-svg to install the Svelte-Inline-SVG plugin; this will reinstate support for SVGs, similar to what we did earlier in the book. 8. We also need to install @paypal/paypal-js for our checkout – we will use this later in this chapter. For this, enter npm install @paypal/paypal-js at the prompt, and then press Enter. 9. We now have the basis for our layout template – we won’t be able to run it up just yet, as there will be one more component to source first! This step we will do in the next exercise when we add pages to our site. 10. At this point, save and close all open files, but you can leave the text editor open for now. 294

Chapter 12

Adapting for Sapper

Okay, we’ve made a good start. We have a base layout in place, with what will be the layout for our new site. Most of what we achieved in this last exercise should be pretty self-explanatory, but let’s take a moment to review the changes in more detail before moving onto the next exercise.

Understanding the Changes Made One of the great things about SvelteKit is that building a site is similar to the original process we used earlier – there are a few things though that change, which will help make it easier for us. One of these is the introduction of a new layout template process. We started by extracting a copy of __layout.js, which will act as the template for our site. Remember how we used the App.svelte file to build up a kind of template? The __layout.js is a private (denoted by the __ in the filename) file that makes this a more formal option; rather than dumping code at the very top (so to speak), we can create a layout using a file designed for this purpose. It has the added benefit of handling routing automatically – we no longer need to rely on the svelte-routing plugin we used earlier in the book! We then copied across the original Header and Footer components from the old site; these we stored in a new components folder under \src in the new site. At the same time, we also brought over copies of the fonts and images library; given the existing location references for these folders were already good, we didn’t have to make any changes. Next up, we then had to edit out references to the Notification component in the layout file – this was triggering errors. The component isn’t essential to getting the primary site working; as an MVP, we can focus on the core elements and come back to this later. We then moved onto installing both Paypal and the Svelte-Inline-SVG plugins; this is something we did earlier in the book for our original site, so it’s just a matter of replicating the same process for the new version. Okay, with our new layout template in place, it’s time to move on and start to add in the page content. We will do this in three parts – we’ll cover adding the product gallery and product page shortly, but let’s start with adding the other content pages to our new site.

295

Chapter 12

Adapting for Sapper

Adding Pages Any ecommerce site on the Internet will need some form of content pages – it will be for pages such as delivery questions, contact, FAQs, and more. We’ve already created the base pages in the previous site, so all we need to do is move them over and adjust them, so they work within a SvelteKit environment. Let’s crack on and look at what we need to do to get them working on our new site.

ADAPTING TO SAPPER – PART 3: ADDING PAGES To set up the content pages, follow these steps: 1. First, we need to copy across the remaining content pages – for this, copy Coffee.svelte, About.svelte, and Contact.svelte from the \src\ pages folder of our original site into the \src\routes folder in the new site. 2. Next, go ahead and rename Home.svelte to Index.svelte – this is required to ensure pages are routed correctly (more on this shortly). 3. At the same time, copy across Modal.svelte, Disclaimer.svelte, and Carousel.svelte from the \src\components folder in the old site to the \src\components folder in our new site. 4. Fire up a Node.js terminal session, and then change the working folder to our new project area. At the prompt, enter npm i yup svelte-yup and press Enter to install the form validation for the Contact page. 5. Next, we need to add a reference to the Disclaimer component into the __ layout.svelte file – for this, go ahead and add this line of code before the closing tag: import   Disclaimer from '../components/Disclaimer.svelte';

6. Go ahead and save, and then close all files – the changes are complete for this exercise.

296

Chapter 12

Adapting for Sapper

We’re starting to make more progress – if you try to run up the site now, it won’t look pretty, but it should still work! We will fix the styling later in this chapter, but for now, let’s review the changes we’ve made in more detail.

Understanding the Changes Made So far, we’ve set up our base site and created a layout template – in the last demo, we started to flesh out our site with the content pages from the original demo. Unfortunately, it’s not a simple case of copying files across like for like; as SvelteKit has routing built-in, we have to make a few changes! The first change is in the copying of the files – we copied them across from \src\components, but put them in \src\routes in the new site. We could store them elsewhere, but given that we’ve referenced their location in __layout.js, it kind of makes sense to keep them with the __layout.js file, at least for now. SvelteKit knows where the files are stored and will automatically route to them as needed. It does raise an important point, though – the location of content-type files is something you will need to consider, particularly for larger sites. We then renamed the Home.svelte file to Index.svelte – this fits in better with the overall structure and routing, but apart from which, the convention of calling the main index file Home.svelte is a little outdated! At the same time, we copied across the Modal, Disclaimer, and Carousel component files and stored them in the new components folder. To round things off, we then installed the form validation components used in Contact.svelte; this is no different from before, but we need to do it here to retain the functionality. We also added a missing reference to the Disclaimer component in the __layout file – putting it here means that we maintain that banner across all pages, not just the home page.

Adding Product Gallery We’re now at the most crucial point – it’s time for us to get our gallery set up, ready for use! Fortunately, we don’t have too many changes to make here – let’s take a look at what we need to do to get the pages working on our new site.

297

Chapter 12

Adapting for Sapper

ADAPTING TO SAPPER – PART 4: ADDING THE PRODUCT GALLERY To get the Products.svelte page operational, follow these steps: 1. First, go ahead and copy the Products.svelte from our old site to the \src\routes folder in the new project area. 2. Next, we need three additional components – copy Cart.svelte and CTAButton.svelte from the original \src\components folder, and drop them into the same place in the new site. Go ahead and edit the import statements at the top of Products.svelte, so they point to the files in the new location. 3. We can remove two imports that are now redundant – we’re not using the Link component from svelte-routing nor the Button.svelte component so that we can remove both imports: import { Link } from "svelte-routing"; import Button from "./components/Button.svelte";

4. Scroll down to this line of code – it contains a reference to a component we no longer need to use:

  {product.name}

5. Go ahead and modify the code as highlighted:

  {product.name}

6. We have one more step, which is to install the Svelte-notifications plugin. For this, switch to a Node.js terminal session, and then make sure to set the working folder to our new project area. 7. At the prompt, enter npm install @beyonk/svelte-notifications and press Enter.

298

Chapter 12

Adapting for Sapper

8. Switch to Products.svelte, and comment out lines 5, 18, and 59 – this might seem a little strange given we’ve just installed the component, but it will throw an error. We’re commenting it out until we can fix it – I will return to this step later in the code review. 9. Go ahead and save and then close all files – the changes are complete for now. We’re almost at the end of creating our replacement site – it’s beginning to take shape now. We’ve had to make a few changes to our product gallery page to get it working, so let’s pause for a moment to review the code changes in more detail.

Breaking the Code Apart So far, we’ve created our initial layout and added content pages – in the last exercise, we went a step further and added one of the most important: our product gallery page. To get this working in our new site, we first copied across the original Products. svelte file, along with Cart.svelte and CTAButton.svelte, before updating the import references in our code. At the same time, we then removed references to two files that were no longer needed and edited one of the links in our code to reflect that change. There is an important point to make – notice how we dropped the page, not into the components folder (which is where it was before), but into the routes folder? It is technically a page as opposed to a component (although it contains elements of both). Given we are referencing the "page" from the navigation, it makes sense to put it with the other pages! We then finished by installing the svelte-notifications plugin before commenting out references in our code. This last step might seem a little strange, but the plugin fell over with several errors when developing code for this book. What makes it even more bizarre is that SvelteKit was used to create the plugin! While it’s a shame that the plugin doesn’t appear to work, for now, we can come back to this later – it’s not essential for an MVP version of our site. Right, we’re creeping ever closer to finishing our site! We have one more section to add in before we can style the site – what’s left? It’s the product page: let’s dive in and take a look at the changes needed to get it working in our new SvelteKit site.

299

Chapter 12

Adapting for Sapper

Adding Product Page We need to add to our product page for this last task – we will use the one we created in the original Svelte site, but it needs a few changes to get it working on our new site. In some cases, these changes will allow us to remove code that is no longer needed, as changes to the structure of the site make it redundant – let’s take a closer look at what is involved in getting the last part of our site operational.

ADAPTING TO SAPPER – PART 5: ADDING PRODUCT PAGE We have a few steps to work through, to get the product page operational – to do so, follow these steps: 1. First, copy across the Product.svelte and Button.svelte files from the original demo; place Product.svelte in the \src\routes folder, and put Button.svelte into the \src\components folder. 2. Crack open the copy of Product.svelte from our new project area – go ahead and remove this line, as it is no longer needed: import { Link } from "svelte-routing";

3. Next, comment out lines 5, 23, and 73 – these relate to the Notifier component we set up earlier in the book, but which isn’t working correctly in SvelteKit. We will come back to this later. 4. Now that we’ve removed the Link component reference, we need to update the link that used it to avoid throwing an error. Go ahead and find this line, and then change Link to= to a href= and /Link to /a: {" a:nth-child(2)"); if (individualURL.indexOf("/product") != -1) {   getShopMenuItem.style.borderBottom = "5px solid #552200"; } else {   getShopMenuItem.style.borderBottom = "none"; }

9. Next, crack open Button.svelte, and replace the styling block at the top of the file with this – it will revert the CSS to normal CSS, as we don’t have the PostCSS processor installed:

10. We’re done with the changes – save and close all open files. 301

Chapter 12

Adapting for Sapper

Yes, we have finally made the transition! We now have all of our files in place, albeit the site won’t look that good (but don’t worry – we’ll fix that shortly). We’ve made a few changes in this last demo to get the product page working, so let’s take a moment to review those changes in more detail before moving on to styling our new site.

Understanding the Changes Made Although we’ve only had to update a handful of pages, the product page is the one that needed the most changes to get it working. In some cases, the changes were expected, such as updating import references. However, we were also able to remove a good chunk of code that was no longer required. I’m a big fan of continuous improvement, so anything that helps in this respect is a good thing! We started by copying across the Product.svelte and Button.svelte files to the \src\components folder in our new site before removing a (now) redundant link to svelte-routing, as the functionality is covered by SvelteKit automatically. At the same time, we also updated one of the links to remove the dependency on the Link component. Next up, we then had to comment out references to the Notification component; this isn’t ideal, but as mentioned in the changes to the Products.svelte component, this is essential. I came across errors being generated while researching this book; in the spirit of taking an MVP approach, I decided to focus on the core elements and come back to these at a later date. We then moved onto creating the [slug].svelte file – yes, it might seem an odd name, but bear in mind that this is a template file, not a regular page! Svelte will use this to create the individual product page based on the link clicked, so in reality, it would become 2.svelte if we clicked the second product, and so on. To complete the new file, we copied the contents of Product.svelte into this file – we could have renamed the original file, but this would leave us without a backup if we had an issue. We then had to make a series of changes to the code itself – first up, we updated the import references before modifying some of the code and removing that which was redundant. We then finished by updating the styling for the Button component – remember that we converted the original version to use PostCSS, which won’t work until we add support for the tool. Phew, we’re done with the code changes: it’s time to get artistic and style our site! This step is my favorite part – being a visual person, it’s nice to see something evolve 302

Chapter 12

Adapting for Sapper

from an elementary site into something more refined. In this case, most of the styling should come across as is, although there will be some changes we need to make – let’s move swiftly on and find out what we need to do to get our site looking more attractive.

M  igrating Styles When it comes to styling any site, this is where we can make a real visual impact – I know writing in the confines of a book means we can’t go to town; we can only do that once we have the basic styles set! For our last exercise, we will reuse many of the original styles from the previous version of our site; this should reduce the amount of work required to make our site presentable. Before we do so, it’s worth taking a look at how the site appears now, with the code complete but not all of the styles in place (Figure 12-2).

Figure 12-2.  The site before additional styling is applied Okay, so it doesn’t look too bad – for a straight "lift and shift," it could have been worse! Thankfully, we can improve on it, which we will do in the next exercise.

For space reasons, I’ve had to compress the styles displayed in print; I would recommend viewing the versions available in the code download, as they will be in their original, uncompressed format.

303

Chapter 12

Adapting for Sapper

ADAPTING TO SAPPER – PART 6: MIGRATING STYLES To get the styles set up, follow these steps: 1. First, go ahead and create a new folder called styles in the \static folder. Inside of this folder, create a new style sheet called styles.css. 2. Next, switch to the App.html file, and then add in a link to the new style sheet under the link for the favicon, thus:

3. Most of the styles we need will already exist in the original global.css file that we created – go ahead and copy the contents of global.css into this new styles.css file. 4. The exception to this is the styling for our navigation – go ahead and remove all of the entries beginning with nav, leaving the rest untouched. We will add in new styles for nav shortly. 5. We still need to make a few amendments, though, to finesse the overall appearance – first up, we need to add in a rule for main, which was originally in App.svelte (it includes the addition of a new max-width property – highlighted, not in the original design): main { display: flex; margin-left: auto; margin-right: auto; padding: 20px; max-width: 1040px; }

6. We need to make the next change to the PayPal container referenced in Checkout.svelte – we need to increase the width to prevent it from jumping. Go ahead and add this rule after the code from the previous step: #paypal-button-container { margin: 30px 0; width: 355px; }

304

Chapter 12

Adapting for Sapper

7. We need to make two more changes – the first of which is in Carousel. svelte. We need to adjust the padding, so add in this extra property as indicated: .papagination {   ...     padding: 4px; }

8. The final change we need to make is to the navigation – I’ve not been happy with the original design, as it needed a hacky change to deal with displaying the product page. Now is a good opportunity to revamp it; go ahead and replace the ... block in __layout.js with this:

  
        
  • Contact


  • 9. Remember how I said we would replace the styling in step 4? Well, here is the replacement – go ahead and copy the code in, block by block, at the end of the file, starting with the main element: nav { background-color: #c59747; }

    10. We need to add in a rule for the unordered list block: nav ul { display: flex; align-items: start; list-style-type: none; margin: 0; width: 420px; margin-left: auto; margin-right: auto; }

    11. Next up comes the rule for each list item and link in that unordered list block: nav ul li { padding: 6px 0; } nav ul li a { position: relative; display: block; text-decoration: none; transition: 0.5s; padding: 5px 15px; font-weight: bold; color: #552200; }

    305

    Chapter 12

    Adapting for Sapper

    I’ve set a 0.5s value for the transition, but you may find this too short; please feel free to increase the value as you see fit. 12. Finally, we have three rules in place to take care of highlighting the menu entry if we hover over it: nav ul li a::after { position: absolute; content: ""; width: 100%; height: 3px; top: 100%; left: 0; background: #552200; transition: transform 0.5s; transform: scaleX(0); transform-origin: right; } nav ul li a:hover { color: #000000; } nav ul li a:hover::after { transform: scaleX(1); transform-origin: left; }

    13. The final step is to save and close any file we have open, ready to the results of our hard work. 14. You can leave a Node.js terminal session open, though – we will need it very shortly. Phew, we’re done with styling our site; it’s time to test. Hold your horses, my dear reader! Yes, we will test very shortly, but before we do so, we should do a quick review of the code we’ve added and cover off a couple of essential points regarding styling code within SvelteKit.

    Breaking Apart the Code Although we’ve covered a lot of code in this last exercise, most of it will be self-­ explanatory; I’ve deliberately tried to reuse code from earlier to make it easier to affect the transition to using SvelteKit. This said, there are a couple of important points we should cover: •

    306

    Remember how we stored styles in various places in the original demo, such as global.css, or within each component? The same principle still applies, but this time as we’re using static CSS, the style sheet has to go into the static folder – this is to tell SvelteKit not to compile the contents during the site’s build. If we were using a tool such as PostCSS or Sass to compile our styles, the code would have to

    Chapter 12

    Adapting for Sapper

    shift to a new folder that Svelte can reference during the compile and build process. •

    I’ve taken the opportunity to refactor some of the markup during the styling process. Some of you may think this isn’t a good approach; I would say that it’s essential to keep a continuous improvement mindset going and that if we can improve on code, then we should. Markup will never reach the final version; if it does, then the site is no longer of any use to us – the same applies to styling!

    Okay, we’ve now reached that point where we need to test our site! Yikes, I wonder, will it work as we expect?

    Testing the Site and Next Steps Right, we can’t put it off any longer. Go ahead and switch back to that Node.js terminal session from the end of the last exercise. At the prompt, enter npm run dev (which should be very familiar by now!), and what do you get? If all is well, we should see something akin to Figure 12-3, shown overleaf.

    Figure 12-3.  Our finished SvelteKit site

    307

    Chapter 12

    Adapting for Sapper

    Wow, it doesn’t look too bad, huh? Sure, there are a couple of changes, and we’ve not built in everything we had before, but it’s a good start! We still have a long way to go before putting this into production use, but we have a good starting base for developing our site into something more refined and ready for customer use. Thinking further afield, though, there are a host of features we could add or investigate for our site – here are a few ideas to get you started: •

    Now that we have good routing built-in by default, what about providing something like a 404 page? I’ve put a brief example into the code download that accompanies this book – we would save it to the \src\routes\ folder, and SvelteKit will take care of routing automatically.



    Accessibility is another factor – this is something we could add into the app.html file, although how we do it will depend on the size of your site.



    How about preprocessing? We built this into our original site; SvelteKit will happily work with most preprocessing tools such as Sass or PostCSS. I would recommend searching on Google for articles, which should turn up something that will help you get it set up.

    Of course, we should not forget some of the areas we were not able to get in place during the migration:

    308



    The Notifier component is one area that needs attention – it was throwing a cannot use import statement outside a module error when I tried to implement it while researching for this book. A check on the website didn’t reveal anything at the time of writing. Could this be a candidate for replacement? Bear in mind that we are using beta software, so we should expect issues such as this in our code!



    Paypal was also complaining of an error – it flagged Error: Document is ready and element #paypal-button-container does not exist in Checkout.svelte at or around line 38. I suspect the placeholder isn’t ready in time, so PayPal is unable to initialize correctly – again, it’s something we should check if we develop the site into something we can put in front of customers.

    Chapter 12



    Adapting for Sapper

    If you take a look at the console log area, you may see a few warnings regarding Svelte slots that are missing; this is one area we should revisit if only to clean up some of the alerts!

    Phew, we’ve covered a lot! These are just a few ideas to consider; I know we’ve not been able to cover everything, but hopefully, what we’ve touched on here and earlier in the book will give you something you can use to develop your future projects.

    Summary SvelteKit may have only been around for less than a couple of years and still be beta software. Still, in that time, it has come on leaps and bounds – throughout this chapter, we’ve seen how easy it is to migrate the core elements from our original Svelte site to this new framework. We covered some practical steps in this chapter, so let’s take a moment to review what we have learned. We started with a quick look at why this chapter was meant to be about SvelteKit’s predecessor and how it was more beneficial to look forward to SvelteKit, before working through the steps to create the initial site for our replacement front-end demo. Next up, we then explored a high-level view of a typical SvelteKit site’s structure before adding a new layout template, ready for us to develop the new site. We then worked through adding pages, the product gallery, and the individual product page template before finishing with restyling the site using existing styles from the original version of our project. We wrapped up with a look at the next steps and confirmed that our site runs; we had set expectations at the start to focus on core elements, so we worked through some ideas as to how we could develop our site into something we can put in front of customers. Sadly, all good things must come to an end, as we’ve now reached the end of the book – it’s been an adventure! I hope you’ve enjoyed reading and working on the examples as much as I have with writing them and that you’ll be able to put this to good use in your future projects.

    309

    APPENDIX

    Getting Help Help, I’m stuck…! In over 20 years of supporting family, friends, and colleagues with IT requests, this is one phrase I hear far too often – indeed, if I had had a dollar for each time, I would be on a remote island somewhere, basking in the sun, drinking whiskey… But I digress. There may well be occasions where you do become stuck on something when working with Svelte – it might be a simpler framework to learn than the likes of Angular, but it doesn’t mean that things will be plain sailing all of the time! If you do become stuck, there are a few sources you can turn to for help: •

    The first port of call should be the interactive tutorial, starting from https://svelte.dev/tutorial/basics, or the Svelte examples page, available from https://svelte.dev/examples#hello-­world. They may not be an exact match for your requirements, but you may find your answer with a little lateral thinking!



    If the query relates to a specific API function, then I would recommend taking a look at the extensive documentation on the Svelte site, at https://svelte.dev/docs.



    If things are such that you need more help (and there will be occasions when this might happen), then feel free to ask in the Svelte Discord chatroom at https://svelte.dev/chat or on Reddit at this URL: https://www.reddit.com/r/sveltejs.



    If you have a more complex query, it may be better to post a question on the Stack Overflow website, at https://www.stackoverflow.com. There are lots of questions tagged with the word Svelte, which may have your answer, or you can ask your own if you can’t find something there that has already been asked.

    © Alex Libby 2022 A. Libby, Practical Svelte, https://doi.org/10.1007/978-1-4842-7374-6

    311

    Appendix

    Getting Help

    I would strongly recommend reading the Code of Conduct at https://stackoverflow.com/conduct; this will help you get a better answer for your questions. Hopefully, this will help you solve that burning question or conundrum – Svelte is a great framework to learn; there are thousands of people out there who already use it and who I am sure will be willing to help encourage others to come into the Svelte family.

    312

    Index A

    C

    addNumber() function, 55 Animating process auditing, 261, 262 banner offering, 277, 278 cart actions, 279–282 code working process, 267 duolingo clone, 266 easing effects, 269 Animista, 274 CSS-based version, 272–274 custom animation, 271 JavaScript, 269–272 partial image, 273 image carousel, 282–285 learning language, 262–268 libraries, 275 transition/easing effects, 263 word animation, 268, 269

    Component creations, 21 App.svelte file code review, 33, 34 component index, 34, 35 source code, 31–33 button, 44–49 CodePen demos, 21 expectations architectural schematic site, 30–32 folder structure, 28 setup process, 27 file formats, 49 footer, 37–39 header, 35–37 principles, 22 product gallery (see Product gallery creation) remaining page, 49 REPL playground browser, 22 button component, 23–25 code review, 26, 27 installation app, 23 updated button, 27 SVG code, 39 testing, 49

    B Button component cart feature, 46–49 HTML markup, 48 passing props, 58 removeItem event handler, 48, 49 steps, 45, 46

    © Alex Libby 2022 A. Libby, Practical Svelte, https://doi.org/10.1007/978-1-4842-7374-6

    313

    Index

    D

    E

    Data management, 53 browser console, 65 context components getContext/setContext methods, 59–61 key-pair value, 62, 63 meaning, 59 differences, 66–68 features, 53, 74–76 functional process derived stores, 72–74 fake customer name, 70–72 passing props, 71 Product.svelte, 69 program code, 74 stores.js file, 68 operating stores, 63–65 program code, 65, 66 props passing button component, 58 code review, 58 running process, 56–58 reactive declaration, 54 source code, 53 value passing, 55, 56 Deployment process actual production, 215, 216 automation, 228–231 branch checking, 218, 219 content/production, 219–222 disclaimer component, 212–215 domain name, 222–227 features, 227 GitHub pages, 214, 220, 224 hosting provider, 215–217 HTTPS access, 225 repository, 217

    Event management, 103 action implementation DOM node, 125 onMount() function, 124–126, 128 reworking code, 126, 127 components, 114 event handlers operation, 106–109 forwarding event createEventDispatcher() function, 114–118 nested components, 114 parameters, 117 response, 116 sayHello() function, 117 handleClick() function, 104, 108 handleSubmit() function, 113 life cycle methods beforeUpdate method, 122, 123 componentDidMount(), 123, 124 components, 118, 119 fetch data, 121 onMount method, 119–122 modal overlay features, 129–131 home page, 131 on:click() method, 131, 132 plugin, 132, 133 program code, 131 modifiers, 109–113 mouseover() method, 105 on:click event handler, 128, 129 onClick() method, 105 preventDefault, 111 theory of reactivity, 104, 105 External libraries benefits, 233 client side/server side

    314

    Index

    differences, 242 dynamic rendering, 241 payment processor, 242 personal (PayPal) account code review, 254 details, 244, 245 front-end site, 247–251 loadScript() function, 248 notifications, 253 starting screen, 246 Svelte demo, 245–247 testing, 252–254 react component migration, 255 onMount() function, 258 react component, 255–258 testing compatability date picker component, 236 flatpickrOptions configuration, 240 mini photo album, 235, 236 onMount() event handler, 236–239 SSR, 241 typewriter effect, 239, 240 third-party libraries, 234–236

    F, G, H, I, J, K Form elements binding principles, 135 checkbox inputs, 138 coffee selector, 141–146 components, 141 contact form feature, 151 formSubmit() function, 157 front-end changes, 152 groundwork, 152

    newly created form, 156 Svelte-Yup library, 151 testing process, 153–158 contenteditable fields, 140 dimensions, 141 each block, 140, 141 handling multiline text, 138 maintaining context, 146–150 music selection, 149 numeric inputs, 137–139 selection, 139 stopOthers() function, 147 subtle differences, 136–138 text input, 135, 136

    L, M, N, O Logic controlling process, 77 App.svelte tab, 91 each block, 81–84 exploring existing code, 93 fetching data, 89–94 handleClick() method, 87 if-else conditions, 77 program code, 80 QR code creation, 78–80 login/out links alternative method, 101 data comparing, 101 fake log process, 94–96 JSON file, 99 loading products, 97–99 loggedIn method, 96, 97 placeholder message, 100, 101 program code, 99 removing item, 84–88 updating process, 94 315

    Index

    P, Q, R Product detail page (PDP), 41–43, 203 Product gallery creation card creation, 41–43 code review, 43, 44 step processing, 39–41 style placeholder, 41

    S, T Sapper content pages, 296, 297 migrating project, 288 migrating styles, 303–306 overview, 287 product page, 300–303 program code, 306 product gallery, 298–300 SvelteKit (see SvelteKit site) testing, 307–309 Server-side rendering (SSR), 12, 241 Single-file component (SFC) principle, 178 Styling process, 159 benefits, 161 features, 161 front-end demo buttons, 168, 169 demo pages, 161, 162 global styles, 162–164 header/footer, 167, 168 product pages/shopping cart, 169–172 program code, 173 updating pages, 164–167 preprocessor, 173–177 prop errors, 159–161 SFC principle, 178 316

    SvelteKit site files/folder structure, 292, 293 initial site, 290 layout template, 294–296 Node.js, 291 steps, 289–291 testing process, 307–309 Svelte project application creation, 5 background process, 18 base app, 15 browsers, 13 comparing process, 11 components (see Component creations) development environment, 2 file and folder structure, 16–19 main.js, 16 Node.js, 15 overview, 2, 3 package.json, 17 react component, 9–12 REPL tool, 5–8 SSR, 12 setup options, 3, 4 Shopify, 2, 3 site installation, 13–15 source code, 8, 9

    U, V, W, X, Y, Z Unit testing browsers, 183 contact pages, 195–199 Cypress configuration, 183–187 debugging, 205–207 describe() block, 198, 203

    Index

    disclaimer component, 191 environment, 183–187 file structure, 190 home page, 191–195 lighthouse, 207, 208 mount() method, 194

    natural language syntax, 188–191 principles, 190 product pages/cart, 199–204 shop test, 202 strategies, 181–183 website components, 186

    317