Home Web Front-end JS Tutorial A gentle introduction to SvelteKit for Google Cloud developers

A gentle introduction to SvelteKit for Google Cloud developers

Jul 17, 2024 pm 07:39 PM

 A gentle introduction to SvelteKit for Google Cloud developers

Introduction

An earlier post in this series (A very gentle introduction to React) introduced readers to the excellent React framework system for developing webapps. SvelteKit is an alternative framework. How does it differ from React and is it any better?

Functionally, I guess there's not that much difference. Most things you can do in React you can do in SvelteKit. And vice-versa. But when you get down to the details, many people feel that SvelteKit has the edge in terms of the ease with which you achieve your "reactive" goals. Svelte means "elegant" - and that's just what it is - a slender, highly adaptable and practical tool.

Personally, I was attracted to SvelteKit because it also tends to push you towards server-side design - ie code that runs on your webapp's Cloud servers rather than in your user's web browser. This is ironic because it was the ease with which you could write and debug client-side code that originally got me hooked on webapp development. But then I discovered how reluctant indexing spiders are to invest effort in "hydrating" client-side code and realised I would just have to put more effort in here (see debugging in SvelteKit, below, to see what's entailed). But there are other reasons why you might consider using server-side code too. Here are a couple:

  • Once you start using third-party services such as Postmark (email despatch) or Paypal (payment collection), you'll realise that it's not a good idea to include their security codes in client-side code. If you can use the "inspector" to view these, so can anyone else. Code that runs server-side is inaccessible.

  • server-side code lives closer to your data and runs faster here than on a client laptop.

SvelteKit makes it easy to play tunes on specifying which bits of your webapp are to run locally and which are to run remotely.

  • In some cases, pages may be entirely server-side rendered - if they contain only static information, Sveltekit will enable you to "pre-render" them. Pre-rendered pages are constructed at build time and downloaded as slabs of pure HTML.
  • Alternatively, they may be entirely client-side rendered.
  • Or yet again, they may run on both. A SvelteKit webapp aiming to deliver optimal response times may initially display just a server-sourced "placeholder" screen to get something, anything, visible (you get great credit with Google's indexing bots here, apparently). This is then "hydrated" by client-side code with information specific to the user-instance.

Let's get down to something a bit more concrete.

Routing in Svelte

Externally, a Sveltekit webapp will look exactly like any classic browser application - a hierarchy of "pages" such as mywebapp/dosomethingwithmyfiles. It's like this because client users expect, and rely on this type of arrangement. But below the surface, a SvelteKit webapp delivers this arrangement in a totally different way to a React webapp. In React these pages are actually all parts of one giant slab of code and requests are routed thither by re-directs operating at the web interface (if that sentence doesn't make any sense to you, have a look at Whats a 'Single-page' webapp?). SvelteKit achieves this by using your project structure to define your page structure. So, if you want to have a mywebapp/dosomethingwithmyfiles page, you need to have a folder named dosomethingwithmyfiles with a +page.svelte file inside it. Once this arrangement is in place, your deployed app delivers a separate physical page for each of its URLs.

Here's a sample source folder structure for a SvelteKit project:

myproject
├───src
│ └───routes
│ └───dosomethingwithmyfiles

Once you've installed SvelteKit (see Svelte for New Developers), this structure will be augmented by a mass of complicated config files and build folders etc. But, for the present, the focus is on the routes folder. This is where you store your page code - and here is where you might start to wonder whether SvelteKit is the right thing for you. Take a tight grip now because this is where things get a bit complicated.

SvelteKit requires you to follow a very strict naming convention for the content of a page folder. Here's a list of the filenames that might see in a dosomethingwithmyfiles folder:

  • dosomethingwithmyfiles/+page.svelte. This file would contain the source for the code that displays the page for URL myproject/dosomethingwithmyfileson the browser screen. Whoah - let that sink in for a moment. When you're working in your VSCode editor on a SvelteKit project with half a dozen different pages, your filebar may display half a dozen tabs all named +page.svelte. Confusing? Yes, I agree.

At first sight, you might feel that this is simply unacceptable. But note that each +page.svelte file is qualified on the editor bar by the name of its folder owner, dosomethingwithmyfiles, or whatever. It's not so difficult to discipline yourself to check for the owner of a +page.svelte before you dive in and start editing. And once you've developed a SvelteKit project or two you'll begin to appreciate the value of the convention in declaring the purpose of the arrangement (as you'll see in a moment there are quite a few variations)

While you're absorbing this shock, let me give you a bit of encouragement. Within a +page.svelte file you might expect to find the same sort of code you'd see in an equivalent React file - a mixture of exotic useState calls to manipulate page state, and JSX to 'react' to this and generate HTML. While a +page.svelte file certainly does the same job, it manages to discard the "exotic" bit and uses plain javascript and pure, undiluted HTMl salted with a sprinkling of special keywords. You may find this refreshing.

Here are a few more standard filenames you might find in a dosomethingwithmyfiles folder:

  • dosomethingwithmyfiles/+page.js, This would contain the source for a file that delivers data to a +page.svelte file (ie, the equivalent of a React useEffect). Code here will run on the server when the page is initially loaded. Subsequently, if the page is re-referenced, the +page.js code runs in the browser with the advantages listed earlier.

     

    Interestingly, if you've suffered in the past from having to "re-program" your javascript brain whenever you switch between writing Web API code to run in the browser and Node.js style to run server-side in a Firebase function you'll be delighted to hear that, in Sveltekit, the Web API version is now perfectly happy to run server-side as well.

     

    Naturally, you'll want to know just how you organise things so that data read by a +page.js file ends up in the associated +page.svelte. Let me say that, for the present, this arrives by SvelteKit magic. The exact mechanism will only become clear once I've described SvelteKit's arrangements for defining "reactive" variables. Hang onto your hat for now.

     

  • dosomethingwithmyfiles/+page.server.js. This is where you would place code that you want to run only on the server (typically for security or performance reasons). As mentioned earlier, you can request that this is pre-rendered and thus constructed at build-time. In this case, performance is simply startling.

     

  • dosomethingwithmyfiles/+layout.svelte. This is where you would place code that sets up those bits of a page common to a whole set of other pages - toolbar headers, for example. A +layout.svelte file applies to every child route and any sibling +page.svelte. You can nest layouts to arbitrary depth. Again, the precise arrangement for inserting the common layout into the recipient pages will be left for later - more Svelte magic.

     

    If a +layout.svelte page needs some data, it can have an attendant +layout.server.js file

     

  • dosomethingwithmyfiles/+server.js. This is where you would place code that you wanted to be available as an "API endpoint" via a parameterised URL such as myProject/dosomethingwithmyfiles?type="pdf". I'll provide more details on this arrangement later.

'Reactive variables' and 'Reactive HTML' in SvelteKit

By 'reactive variables' I mean data items that cause the browser page to re-render when they change. By 'reactive HTML' I mean HTML instrumented to make it respond to these changes.

In React, you'll recall, reactive variables are declared using a useState expression that defines the variables as properties of a state object. The declaration also specifies initial property values and a function to change them.

Here's an example - a React webapp that displays a popup that disappears when you click it:

import React, { useState } from "react";

const [screenState, setScreenState] = useState({popupVisible: true,});

return (
    <div>
        <h1 style={{textAlign: "center"}}
            onClick = {() => {setScreenState({popupVisible: !screenState.popupVisible})}}>
        Main Page - Click to toggle popup
        </h1>

    {screenState.popupVisible && 
        <div 
            style={{ textAlign: "center", marginLeft: "auto", marginRight: "auto", height: "2rem", width: "25rem", backgroundColor: "gainsboro" }}
            onClick = {() => {setScreenState({popupVisible: !screenState.popupVisible})}}>
            <h2> Popup Window - Click to Hide popup</h2>
        </div>  
    }
    </div>
)
Copy after login

In Svelte (I'm now talking about the language as opposed to the framework in which it operates) you might achieve this effect in a src/routes/demo/+page.svelte file by simply declaring popupVisible as a javascript variable

<script>
    let popupVisible = false;
</script>

 <div>
    <h1 style="text-align: center" 
        on:click={() => (popupVisible = !popupVisible)}>
        Main Page - Click to toggle popup
    </h1>

    {#if popupVisible}
        <div
            style="text-align: center; margin-left: auto; margin-right: auto; height: 2rem; width: 25rem; background-color: gainsboro"
            on:click={() => (popupVisible = !popupVisible)}
        >
            <h2>Popup Window - Click to Hide popup</h2>
        </div>
    {/if}
</div>
Copy after login

Here's a summary of the key differences:

  • Svelte uses a standard Javascript let declaration to introduce state variables instead of the strange React useState expression

  • Svelte uses a down to earth #if 'logical expression' keyword to replace the awkward JSX {'logical expression' &&syntax. This makes your code much more readable. Svelte also provides associated else and each keywords.

  • Svelte uses plain CSS to define HTML classes rather than the perplexing JSX style objects (eg {{textAlign: "center"}}).

Note also that the demo/+pagesvelte file defined above will run directly in the browser as /demo. To run the React version you would have to put some code into an associated src/main.jsx file to define the new route.

Inputs: Local Functions, Actions and API endpoints

Keyboard input in React generally uses the following pattern:

const [myState, setMyState] = useState({myProperty: "",});

function handleChange({ target }) {
    setMyState({ ...myState, [target.name]: target.value });
};

return (
    <input name="myProperty"
        value={myState.myProperty}
        onChange={handleChange} />
)
Copy after login

Here, an input labelled as "myProperty" fires a general-purpose handleChange function every time you press a key. In handleChange its value is extracted and applied to the page's state to trigger a re-render.

Svelte thinks this is too complicated and introduces a "bind" keyword to its input syntax. This automatically transmits changes to an associated state variable. A Svelte version of the above thus looks like this:

<script>
    let myProperty = "";
</script>
<input bind:value={myProperty} />
Copy after login

The bind keyword is also used to enable you to create two-way communication between parent and child components. This is a powerful feature.

An interesting feature of Svelte is that it encourages you to use forms and server-side processing for input handling. Thus it's perfectly permissible in Svelte to launch a client-side function like this:

<script>
    let myProperty = "";
    function commitChange() {
        // Use the global myProperty variable to update server storage
    }
</script>

<span>myProperty = </span><input bind:value={myProperty}  />
<button on:click={commitChange}>Commit Change</button>
/>
Copy after login

Svelte docs correctly insist that interactions like this are better handled by forms and server-side processing in a +page.server.js file. Here the validation and submission of the user input can be safely protected from the sort of interference possible in client-based code. Here also, any subsequent processing can be performed with maximum efficiency.

To implement this view, Svelte provide a neat automatic link between a form reading data on a +page.svelte and a function handling the processing of that data in the associated +page.server.js file. Here's an example:

src/routes/login/+page.svelte
<form method="POST">
    <span>myProperty = </span><input name="myProperty">
    <button>Commit Change</button>
</form>

src/routes/login/+page.server.js
export const actions = {
    default: async (event) => {
        // TODO handle the processing for the input read by the form on +page.svelte
    }
};
Copy after login

Note that no Javascript has been used in the form - no "on click" or "on submit", for example. The linkage has been established entirely through "Svelte magic".

In practice, of course, a +page.svelte file is likely to want to be the source of multiple "actions". See Svelte Form Actions for details of how Svelte manages this. (Note that Svelte docs are organised under two URLs: kit.svelte.dev for framework topics like routing and svelte.dev for elements of the language itself)

Finally, to conclude this section, suppose you wanted users to be able to call on the service of an action by referencing it directly through a javascript "fetch" (or, at its simplest by launching a parameterised url via the browser - eg https:// mySite/myPage?param1=3 etc). This is where you would use a +server.js file to create an API "endpoint" function. Firebase users might well use such an arrangement where they had previously used a Firebase function. Not the least advantage of this would be that testing and debugging could be done in the Sveltekit server rather than the Firebase emulator.

Components

  • 1-way bindings

Each +page.svelte file defines a component, and you mark variables declared here as "props" - ie make them accessible to "consumers" of the component - by adding the export keyword to their declarations. So, if you're still wondering how a +page.svelte file gets its data from +page.server.js - this is how it's done. A +page.svelte file wanting to receive "load" data from its +page.server.js (or +page.js) file just needs to put something like the following in its

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

Video Face Swap

Video Face Swap

Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Tools

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

Hot Topics

Java Tutorial
1657
14
PHP Tutorial
1257
29
C# Tutorial
1230
24
Demystifying JavaScript: What It Does and Why It Matters Demystifying JavaScript: What It Does and Why It Matters Apr 09, 2025 am 12:07 AM

JavaScript is the cornerstone of modern web development, and its main functions include event-driven programming, dynamic content generation and asynchronous programming. 1) Event-driven programming allows web pages to change dynamically according to user operations. 2) Dynamic content generation allows page content to be adjusted according to conditions. 3) Asynchronous programming ensures that the user interface is not blocked. JavaScript is widely used in web interaction, single-page application and server-side development, greatly improving the flexibility of user experience and cross-platform development.

The Evolution of JavaScript: Current Trends and Future Prospects The Evolution of JavaScript: Current Trends and Future Prospects Apr 10, 2025 am 09:33 AM

The latest trends in JavaScript include the rise of TypeScript, the popularity of modern frameworks and libraries, and the application of WebAssembly. Future prospects cover more powerful type systems, the development of server-side JavaScript, the expansion of artificial intelligence and machine learning, and the potential of IoT and edge computing.

JavaScript Engines: Comparing Implementations JavaScript Engines: Comparing Implementations Apr 13, 2025 am 12:05 AM

Different JavaScript engines have different effects when parsing and executing JavaScript code, because the implementation principles and optimization strategies of each engine differ. 1. Lexical analysis: convert source code into lexical unit. 2. Grammar analysis: Generate an abstract syntax tree. 3. Optimization and compilation: Generate machine code through the JIT compiler. 4. Execute: Run the machine code. V8 engine optimizes through instant compilation and hidden class, SpiderMonkey uses a type inference system, resulting in different performance performance on the same code.

JavaScript: Exploring the Versatility of a Web Language JavaScript: Exploring the Versatility of a Web Language Apr 11, 2025 am 12:01 AM

JavaScript is the core language of modern web development and is widely used for its diversity and flexibility. 1) Front-end development: build dynamic web pages and single-page applications through DOM operations and modern frameworks (such as React, Vue.js, Angular). 2) Server-side development: Node.js uses a non-blocking I/O model to handle high concurrency and real-time applications. 3) Mobile and desktop application development: cross-platform development is realized through ReactNative and Electron to improve development efficiency.

Python vs. JavaScript: The Learning Curve and Ease of Use Python vs. JavaScript: The Learning Curve and Ease of Use Apr 16, 2025 am 12:12 AM

Python is more suitable for beginners, with a smooth learning curve and concise syntax; JavaScript is suitable for front-end development, with a steep learning curve and flexible syntax. 1. Python syntax is intuitive and suitable for data science and back-end development. 2. JavaScript is flexible and widely used in front-end and server-side programming.

How to Build a Multi-Tenant SaaS Application with Next.js (Frontend Integration) How to Build a Multi-Tenant SaaS Application with Next.js (Frontend Integration) Apr 11, 2025 am 08:22 AM

This article demonstrates frontend integration with a backend secured by Permit, building a functional EdTech SaaS application using Next.js. The frontend fetches user permissions to control UI visibility and ensures API requests adhere to role-base

From C/C   to JavaScript: How It All Works From C/C to JavaScript: How It All Works Apr 14, 2025 am 12:05 AM

The shift from C/C to JavaScript requires adapting to dynamic typing, garbage collection and asynchronous programming. 1) C/C is a statically typed language that requires manual memory management, while JavaScript is dynamically typed and garbage collection is automatically processed. 2) C/C needs to be compiled into machine code, while JavaScript is an interpreted language. 3) JavaScript introduces concepts such as closures, prototype chains and Promise, which enhances flexibility and asynchronous programming capabilities.

How do I install JavaScript? How do I install JavaScript? Apr 05, 2025 am 12:16 AM

JavaScript does not require installation because it is already built into modern browsers. You just need a text editor and a browser to get started. 1) In the browser environment, run it by embedding the HTML file through tags. 2) In the Node.js environment, after downloading and installing Node.js, run the JavaScript file through the command line.

See all articles