Featured resource
pluralsight tech forecast
2025 Tech Forecast

Which technologies will dominate in 2025? And what skills do you need to keep up?

Check it out
Hamburger Icon
  • Labs icon Lab
  • Core Tech
Labs

Guided: Build a Code Snippet Manager in Svelte

In this guided lab, you'll be building a dynamic code snippet manager. You'll dive into Svelte's component-based architecture, crafting an interactive interface with ease. You'll discover the power of Svelte's reactive state management, allowing you to handle app states, and harness Svelte's simplicity of form handling, seamlessly capturing user input. Finally, you'll learn about local storage in JavaScript, enabling your app to persist data across browser sessions.

Labs

Path Info

Level
Clock icon Intermediate
Duration
Clock icon 41m
Published
Clock icon Apr 12, 2024

Contact sales

By filling out this form and clicking submit, you acknowledge our privacy policy.

Table of Contents

  1. Challenge

    Understanding Svelte Basics

    Welcome to this guided lab. You will be building a Code Snippet Manager in Svelte, but first, let's talk about the fundamental concepts of Svelte and how it facilitates building reactive web applications.

    Svelte is a modern JavaScript framework for building user interfaces. Unlike other frameworks that do a lot of work in the browser, Svelte shifts that work into a compile step that happens when you build your app, resulting in highly optimized vanilla JavaScript.

    The core philosophy behind Svelte is to write less code, with its reactive updates model being straightforward and intuitive.

    Svelte applications are composed of components, which are encapsulated parts of your application that manage their state and presentation. Components are typically written in single-file components (.svelte files) that include HTML, JavaScript, and CSS.

    Svelte is gaining popularity for a few reasons:

    • Ease of Learning: With less boilerplate and a straightforward approach, Svelte is easier to grasp for beginners.

    • Performance: Due to compile-time optimizations, Svelte applications can be more performant, especially for smaller projects.

    • Readability and Maintenance: Svelte's syntax is clean and easy to understand, promoting maintainability.

    Because this environment does not have internet access this project has already been scaffolded for you using Vite, required assets have been downloaded, and unneeded files have been removed. (Picnic CSS) has also been added to provide basic styling of native HTML elements.

    In the terminal, run npm run dev -- --host to start the dev server. The application will be available with hot module replacement by clicking on the Web Browser tab, and clicking the Open in new browser tab icon, or you can open a new browser tab by clicking the following link: {{localhost:5173}}.

    info> The solution for each task in this lab are available for your reference in the solution directory.

  2. Challenge

    Setting Up the Component and Styles

    Start by setting up the component and importing necessary CSS files and JavaScript modules.

    You'll need to import two CSS files into your Svelte component. These files can be found under the src/assets folder.

    The first line must import a CSS framework (picnic.min.css) for styling, and the second line imports custom styles (style.css) specific to this component.

    This setup is crucial for ensuring that the styles are applied to the component when it renders. The next step is to initialize the state variables for the Code Snippet Manager application.

    You must add specific variables to the script tag within the App.svelte file.

    Declare a snippets variable and set it to an empty array. Then declare a title variable as an empty string. Following that, declare a code variable as an empty string. Finally, declare an editingIndex variable and set its value to -1.

    By doing this, you declare and initialize state variables using Svelte's reactive state management.

    Essentially, snippets is an array that will hold the code snippets, title and code are strings that will hold the current input from the user, and editingIndex is used to track if the user is editing an existing snippet (-1 indicates no snippet is being edited).

  3. Challenge

    Managing Snippets

    Throughout this step, there are two things you must accomplish:

    1. Write a function to load snippets from local storage.

    2. Save Snippets to Local Storage. Now, you are going to write a function to load snippets from local storage.

    Open the App.svelte file. Add the following pseudo-code within the script tag.

    const loadSnippets = () => {
        const savedSnippets = << 1 >>.getItem('snippets');
        if (savedSnippets) {
          snippets = JSON.<< 2 >>(savedSnippets);
        }
    };
    

    You must replace << 1 >> and << 2 >>.

    So, << 1 >> represents the local storage and << 2 >> indicates the action of parsing the value of savedSnippets.

    This function checks local storage for saved snippets using << 1 >>.getItem('snippets').

    If there are saved snippets, it parses them from JSON into the snippets array, making them available in the component's state for rendering.

    This function is designed to retrieve a list of saved code snippets from the browser's local storage and load them into the application's state.

    The function makes use of the Web Storage API, specifically the local storage object, to persist data across browser sessions for a specific domain.

    const loadSnippets = () => { ... }; defines a function using arrow function syntax and assigns it to the constant loadSnippets. This syntax is a concise way to write functions in JavaScript. The function can be called later in the code by referencing its name, loadSnippets().

    const savedSnippets = << 1 >>.getItem('snippets'); attempts to retrieve the item with the key snippets from the browser's local storage.

    The << 1 >>.getItem method returns the value associated with the given key if it exists; otherwise, it returns null. The result is assigned to the savedSnippets variable.

    << 1 >> is a key-value storage that allows web applications to store data persistently in the browser.

    Each item stored in << 1 >> persists across browser sessions until explicitly deleted. Values are stored as strings.

    if (savedSnippets) { ... } checks if savedSnippets is truthy.

    Since << 1 >>.getItem returns null when the requested key does not exist, this condition effectively checks whether any snippets were previously saved.

    If savedSnippets is not null (meaning some snippets were found), the block of code inside the if statement is executed.

    snippets = JSON.<< 2 >>(savedSnippets); parses the string retrieved from local storage into a JavaScript object or array.

    The JSON.<< 2 >> method is used because data is stored in local storage as a string, but the application needs to work with the data as a JavaScript object or array.

    This line assumes that the saved snippets are stored in JSON format (a common practice for serializing complex data structures for storage).

    After parsing, the resulting object or array is assigned to the snippets variable, effectively loading the saved snippets into the application's state. Next, you must implement a function to save the current state of snippets to local storage. You can name this function saveSnippets.

    Open the App.svelte and add the following code within the script tag.

    const saveSnippets = () => {
        << 1 >>.setItem('snippets', JSON.<< 2 >>(snippets));
    };
    

    << 1 >> represents the local storage object.

    << 2 >> represents the operation to convert into a string representation a JSON value.

    This function serializes the snippets array to a JSON string and saves it in local storage.

    This ensures that the snippets are persisted between page reloads or when closing and reopening the browser.

    This function is designed to save the current state of the snippets array to the browser's local storage.

    It achieves this by serializing the snippets array into a JSON string and then storing it with the key snippets.

    const saveSnippets = () => { ... }; creates a new constant saveSnippets that stores the function. This function can be invoked later in the code by calling saveSnippets(). The use of arrow function syntax provides a concise way to define the function.

    JSON.<< 2 >>(snippets) converts the snippets array into a JSON string. The JSON.<< 2 >> method is used for serializing JavaScript objects or arrays into a string format.

    This is necessary because the Web Storage API (which includes local storage) only supports storing data as strings.

    Serializing the array allows complex data structures like objects or arrays to be stored as a text representation.

    << 1 >>.setItem('snippets', JSON.<< 2 >>(snippets)); stores the serialized snippets array in the browser's local storage under the key snippets.

    The << 1 >>.setItem method takes two arguments: the first is the key under which the data should be stored (snippets in this case), and the second is the data to store (the JSON string representation of the snippets array).

    Once this method is executed, the snippets data is persisted in the browser's local storage, making it available across browser sessions and reloads.

    The saveSnippets function is crucial for web applications that need to persist data locally on the user's device.

    By storing data in local storage, the application can remember the user's data even after the browser is closed or the page is reloaded.

    This function, in particular, allows the application to save the current state of code snippets, ensuring that user-generated content is not lost between sessions.

  4. Challenge

    Adding, Editing, and Deleting Snippets

    It's time to look at how you can implement Adding, Editing, and Deleting Snippets.

    You will do this in three stages:

    1. Adding a New Snippet
    2. Editing a Snippet
    3. Deleting a Snippet You must create a function to add a new snippet or update an existing one.

    Open the App.svelte file and add an addSnippet function within the script tag. The function's pseudo-code is as follows.

    const addSnippet = () => {
        if (title.trim() && code.trim()) {
          if (editingIndex > -1) {
            << Do something here... >>
          } else {
            << Do something else here... >>
          }
          saveSnippets();
          title = '';
          code = '';
        }
    };
    

    This function first checks if both title and code are not empty.

    If editing an existing snippet (indicated by editingIndex being non-negative), it updates the snippet at the given index. Which is what you must do in the following section: << Do something here... >>

    Otherwise, it adds a new snippet to the end of the snippets array. Which is what you must do in the following section: << Do something else here... >>

    After adding or updating, it calls saveSnippets to persist changes and resets title and code for the next input.

    if (title.trim() && code.trim()) { ... } checks that both title and code are not empty or just whitespace.

    if (editingIndex > -1) { ... } else { ... } determines if this is an edit operation (if editingIndex is set) or an addition of a new snippet.

    You must then update the snippet at editingIndex with the new title and code, here: << Do something here... >>

    On the other hand, << Do something else here... >>adds a new snippet to the snippets array.

    saveSnippets(); calls the saveSnippets function to save the updated snippets to local storage.

    title = ''; and code = ''; resets the title and code variables, clearing the form inputs.

    This function is integral to the functionality of a code snippet manager, allowing users to seamlessly add new snippets or update existing ones while ensuring that their changes are saved across browser sessions. Your objective is to enable snippet editing by filling the form with the snippet's current details.

    To do that you must open App.svelte and within the script tag, add the following editSnippet function.

    const editSnippet = (index) => {
        editingIndex = index;
       << Access the title property >>
       << Access the code property >>
    };
    

    This function sets editingIndex to the index of the snippet to be edited, and assigns title and code to the values of the snippet, allowing the user to see and modify the existing snippet details in the form.

    editingIndex = index;:

    This line marks which snippet is currently being edited by assigning its array index to editingIndex.

    This is crucial for the add/update logic to correctly update this snippet instead of creating a new one.

    << Access the title property >>:

    This line assigns the title of the snippet being edited to the title variable.

    Since title is likely bound to an input field in the UI, this action automatically populates that field with the snippet’s title.

    << Access the code property >>:

    Similar to the previous line, this assigns the code of the snippet being edited to the code variable, filling in the corresponding input field in the UI with the snippet’s code.

    The editSnippet function is integral for enabling the edit functionality within a snippet manager application.

    By setting the editing context and populating the form with the snippet's current content, it provides a seamless user experience for editing snippets. Next, you must implement a function to delete a snippet.

    So, open the App.svelte file and add the following function within the script tag.

    <script>
      const deleteSnippet = (index) => {
        << Do something here >>
        saveSnippets();
      };
    </script>
    

    This function removes a snippet from the snippets array based on its index.

    Within << Do something here >> you must use the filter method to create a new array excluding the snippet at the given index, then saves the updated list to local storage.

    << Do something here >>:

    This line creates a new snippets array excluding the snippet at the given index. The is a placeholder for the element value, which is not used in the condition.

    You must use a condition i !== index to ensure that all snippets except the one to be deleted are included in the new array.*

    saveSnippets();:

    This line calls the saveSnippets function to persist the updated list of snippets to local storage.

    This is crucial for maintaining the integrity of the snippet collection across different sessions.

    The deleteSnippet function plays a vital role in managing the lifecycle of snippets within the application, allowing users to remove snippets they no longer need.

  5. Challenge

    User Interface and Interaction

    Now, you will explore how to create the form for adding and editing snippets.

    You will do this in two separate tasks:

    1. Construct a form in HTML that allows users to input a title and code for a snippet.

    2. Display Snippets and Provide Edit and Delete Options. In this task, you must construct a form in HTML that allows users to input a title and code for a snippet.

    To do that, open the App.svelte file and after the closing script tag, let's add the following code.

    <h1>Code Snippet Manager</h1>
    
    <div class="snippet-container">
      <form on:submit|preventDefault={addSnippet}>
        <label>Title:
          << Add the Title Input Field here >>
        </label>
        <label>Code:
          << Add the Code Input Field here >>
        </label>
          << Add the Submit button here >>
      </form>
    </div>
    

    Please make sure you use the correct spacing and indentation

    This HTML structure creates a user interface for the snippet manager. It includes a form with two fields: one for the snippet's title and another for the code.

    You must use the bind:value directive to create a two-way binding between the form inputs and the component's state variables (title and code), ensuring the inputs are synchronized with the component's state.

    The form submission is handled by the addSnippet function, and the button label dynamically changes based on whether the user is adding a new snippet or updating an existing one.

    <h1>Code Snippet Manager</h1>: This line creates a heading (H1) for the application, serving as the title of the page or section. It indicates the purpose of the application to the user.

    <div class="snippet-container">...</div> encloses the form used for inputting snippet details.

    The class="snippet-container" attribute applies specific styling to this div, which could include padding, margins, backgrounds, etc., to visually distinguish or organize the layout.

    <form on:submit|preventDefault={addSnippet}>...</form> defines a form with an event handler for the submit event.

    The on:submit|preventDefault directive prevents the default form submission behavior (which typically refreshes the page) and instead calls the addSnippet function when the form is submitted.

    This function handles adding a new snippet or updating an existing one based on the state of editingIndex.

    << Add the Title Input Field here >>: This line creates a labeled input field for entering the title of the snippet.

    You must use the bind:value={title} directive to creates a two-way binding between the input's value and the title variable in the component's script.

    This means any change to the input field updates title, and any programmatic change to title updates the input field.

    You must use a placeholder attribute to provide a greyed-out text inside the input box, guiding the user on what to enter.

    << Add the Code Input Field here >>: Similar to the title input but for the snippet’s code.

    Here, you should use a textarea, which is used instead of an input to accommodate multi-line text input, allowing users to paste or type in code snippets.

    You must also a bind:value={code} directive to bind the textarea content to the code variable in the script.

    << Add the Submit button here >>: Here, you must define a button for submitting the form. The button's label dynamically changes between "Update Snippet" and "Add Snippet" depending on whether editingIndex is greater than -1 (indicating an edit operation) or not.

    This provides contextual feedback to the user about the action that will be performed upon clicking the button.

    This code snippet effectively creates a user interface for managing code snippets, allowing users to add new snippets or edit existing ones within the same form.

    The use of Svelte's reactive bindings and event handling makes the form interactive and directly tied to the application's state, providing a seamless user experience. Now, you must go ahead and display each snippet with options to edit or delete.

    To do that, open the App.svelte file and after the form that was added in the previous task, add the following code.

    <ul>
      << Iterate through code snippet items >>
        <li>
          <strong>{snippet.title}</strong>
          <pre>{snippet.code}</pre>
          <button on:click={() => editSnippet(index)}>Edit</button>
          <button on:click={() => deleteSnippet(index)}>Delete</button>
        </li>
      {/each}
    </ul>
    

    Please make sure you use the correct spacing and indentation

    This code iterates over the snippets array and renders each snippet in a list.

    For each snippet, it displays the title and code, and provides "Edit" and "Delete" buttons.

    The "Edit" button calls editSnippet with the snippet's index, filling the form with the snippet's details for editing.

    The "Delete" button calls deleteSnippet with the index, removing the snippet from the list.

    << Iterate through code snippet items >>: Here, you must use a directive to iterate over the snippets array, rendering a list item (<li>) for each snippet.

    For each iteration, you must assign the current snippet to a temporary variable snippet and the current index to index.

    You must use (snippet.title), which is the part that is a key expression that helps Svelte identify each list item uniquely, optimizing the reactivity system for updates, additions, or deletions in the snippets array.

    This is particularly useful for performance and preventing unnecessary DOM updates.

    <strong>{snippet.title}</strong>: For each snippet, the title is displayed in bold using the <strong> tag. The title is accessed from the current snippet object.

    <pre>{snippet.code}</pre>: The code of the snippet is wrapped in a <pre> tag, which is used to display preformatted text.

    This ensures that the code’s formatting and spacing are preserved in the display. The snippet.code is the current snippet’s code.

    <button on:click={() => editSnippet(index)}>Edit</button>: This button, when clicked, calls the editSnippet function and passes the current index of the snippet.

    The function is responsible for setting up the application state for editing the selected snippet, typically by populating form fields with the snippet’s title and code for editing.

    <button on:click={() => deleteSnippet(index)}>Delete</button>: Similarly, this button invokes the deleteSnippet function with the current index upon a click event, which removes the snippet from the snippets array and updates the list.

  6. Challenge

    Initialization and Reactivity

    The last step required to finish off the Code Snippet Manager, is to initialize and make the app reactive. Next, you must ensure that snippets are loaded when the component mounts and react to changes.

    Within the App.svelte file add the following code before the closing script tag.

    onMount(loadSnippets);
    

    Add the following code after the other two import statements.

    << Import onMount >>
    

    This code uses Svelte's onMount lifecycle function to call loadSnippets when the component is first rendered.

    onMount: This is a lifecycle function provided by Svelte that runs after the component is first rendered and attached to the document's DOM.

    It's a perfect place to run initialization code, such as fetching data, adding event listeners, or in this case, loading saved snippets from local storage.

    Usage: onMount is called with a function as its argument. The function you pass to onMount will be executed as soon as the component has been inserted into the DOM.

    It's important to note that onMount is asynchronous and can return a cleanup function that will be called when the component is destroyed, although that's not being used in this particular case.

    loadSnippets: This function's role, as suggested by its name, is to load snippet data.

    Although the specifics of loadSnippets are not provided in the context, based on common patterns, it likely retrieves data from local storage (or another persistence layer), and initializes the component's state with this data, making the snippets available for display or further manipulation in the component.

    The reason loadSnippets is called within onMount rather than directly in the script body is to ensure that the component is fully mounted in the DOM before attempting to load and display the snippets.

    This can be particularly important for operations that may require DOM manipulation or the existence of child components that are also being dynamically loaded or rendered based on the fetched data.

  7. Challenge

    Completion

    By following these steps and tasks, you will have recreated the functionality of the provided App.svelte file, learning about Svelte's capabilities for reactive state management, component lifecycle, and user interaction along the way.

    To make sure you've done things right, feel free to compare the step06_task01.svelte or final.svelte code against the App.svelte code you wrote.

    Well done for following along this guided lab. You've done a great job.

Eduardo is a technology enthusiast, software architect and customer success advocate. He's designed enterprise .NET solutions that extract, validate and automate critical business processes such as Accounts Payable and Mailroom solutions. He's a well-known specialist in the Enterprise Content Management market segment, specifically focusing on data capture & extraction and document process automation.

What's a lab?

Hands-on Labs are real environments created by industry experts to help you learn. These environments help you gain knowledge and experience, practice without compromising your system, test without risk, destroy without fear, and let you learn from your mistakes. Hands-on Labs: practice your skills before delivering in the real world.

Provided environment for hands-on practice

We will provide the credentials and environment necessary for you to practice right within your browser.

Guided walkthrough

Follow along with the author’s guided walkthrough and build something new in your provided environment!

Did you know?

On average, you retain 75% more of your learning if you get time for practice.