Rendering Snippets


Useful Links

Table Demo


NameAgeEmailPhone
Kendra Weissnat-Ziemann41Lucious23@hotmail.com(852) 838-0609
Eleanor Hirthe28Dion38@gmail.com(279) 388-6308
Helen Nolan22Casimir.Stokes@gmail.com(618) 580-1053
Richard Bartell-Conn36Adolf51@gmail.com(359) 280-6211
Hubert Gorczany84Madaline27@hotmail.com(444) 771-0168
Clint Jenkins89Linnie22@hotmail.com(796) 471-3480
Mr. Melvin Leuschke-MacGyver66Ressie.Smith@yahoo.com(383) 241-5706
Eddie Dickens IV32Tad18@yahoo.com(698) 637-5272
Christian Conroy77Irwin.Lubowitz@gmail.com(601) 550-2439
Earnest West83Garrett_Crist@hotmail.com(761) 925-7502

Explanation


When you don't want to make an entire component for a small piece of reusable code, snippets are a great way to encapsulate and reuse logic. In this example, we'll create snippets for rendering text in a <strong> tag and email addresses as clickable mailto links.

You should already know how to make a basic table before proceeding.

Defining Snippets

Snippets can be defined in Svelte either directly in the markup or in the script tag. Here, we use two methods to define our snippets:

🗒️ NOTE: The implementation of snippets within this repo only works with snippets that take one argument.

Markup Snippet

Using Svelte's {#snippet ...} block, you can define a reusable snippet directly in your component's markup. For example, the snippet strongSnippet is defined to render its content in a <strong> tag:

{#snippet strongSnippet(content: string)}
    <strong>{content}</strong>
{/snippet}

Script (Raw) Snippet

Snippets can also be created programmatically in the script tag using the createRawSnippet function. This approach is useful when you do not need to use a Svelte component in your snippet.

<script lang="ts">
  import { createRawSnippet } from 'svelte';

  const mailtoSnippet = createRawSnippet<[string]>((email) => {
    const emailAddress = email();
    return {
      render: () => `<a href="mailto:${emailAddress}">${emailAddress}</a>`,
      // Optional - Setup function to run when the snippet is first rendered
      setup: () => {
        // Example of using a Svelte effect to implement reactivity
        $effect(() => {
          node.textContent = email();
        });
      }
    };
  });
</script>

This mailtoSnippet generates a clickable email link, using the provided email address.

Column Definitions

Next, we define a set of columns for our table. The column definition array specifies how each cell should be rendered, and this is where renderSnippet comes in. This function allows you to use the snippets defined earlier to customize the cell content.

Here's an example of how we use renderSnippet with our snippets in the column definitions:

<script lang="ts">
  import { createRawSnippet } from 'svelte';
  import { createColumnHelper } from '$lib/table'; 
  import { type UserProfile } from '$lib/services/user-profile'; 

  const mailtoSnippet = createRawSnippet<[string]>((email) => { 
    const emailAddress = email(); 
    return { 
      render: () => `<a href="mailto:${emailAddress}">${emailAddress}</a>` 
    }; 
  }); 

  const colHelp = createColumnHelper<UserProfile>(); 

  const columnDefs = [ 
    // Column def using snippet from markup 
    colHelp.accessor('name', { 
      header: 'Name', 
      cell: ({ cell }) => renderSnippet(strongSnippet, cell.getValue()) 
    }), 
    colHelp.accessor('age', { header: 'Age' }), 
    // Column def using snippet from above 
    colHelp.accessor('email', { 
      header: 'Email', 
      cell: ({ cell }) => renderSnippet(mailtoSnippet, cell.getValue()) 
    }), 
    colHelp.accessor('phone', { header: 'Phone' }) 
  ]; 
</script>

{#snippet strongSnippet(content: string)}
  <strong>{content}</strong>
{/snippet}

🗒️ NOTE: You can also use renderSnippet with the header field of each column.

Setting Up the Table

After defining the columns, the next step is to set up the table using the createSvelteTable function. This function initializes the table with the specified data, columns, and core row model.

<script lang="ts">
  import { createRawSnippet } from 'svelte'; 
  import { createColumnHelper } from '$lib/table'; 
  import { createColumnHelper, createSvelteTable, getCoreRowModel } from '$lib/table'; 
  import { type UserProfile } from '$lib/services/user-profile'; 
  import { type UserProfile, userProfiles } from '$lib/services/user-profile'; 

  const mailtoSnippet = createRawSnippet<[string]>((email) => {
    const emailAddress = email();
    return {
      render: () => `<a href="mailto:${emailAddress}">${emailAddress}</a>`
    };
  });

  const colHelp = createColumnHelper<UserProfile>();

  const columnDefs = [
    colHelp.accessor('name', {
      header: 'Name',
      cell: ({ cell }) => renderSnippet(strongSnippet, cell.getValue())
    }),
    colHelp.accessor('age', { header: 'Age' }),
    colHelp.accessor('email', {
      header: 'Email',
      cell: ({ cell }) => renderSnippet(mailtoSnippet, cell.getValue())
    }),
    colHelp.accessor('phone', { header: 'Phone' })
  ];

  const table = createSvelteTable({ 
    data: userProfiles, 
    columns: columnDefs, 
    getCoreRowModel: getCoreRowModel() 
  }); 
</script>

{#snippet strongSnippet(content: string)}
  <strong>{content}</strong>
{/snippet}

Rendering the Table

Finally, to render the table itself, we use the FlexRender component. FlexRender is responsible for dynamically rendering the table's cells based on the content and context provided.

<table>
  <thead>
    <tr>
      {#each table.getHeaderGroups() as headerGroup}
        {#each headerGroup.headers as header}
          <th>
            <FlexRender content={header.column.columnDef.header} context={header.getContext()} />
          </th>
        {/each}
      {/each}
    </tr>
  </thead>
  <tbody>
    {#each table.getRowModel().rows as row}
      <tr>
        {#each row.getVisibleCells() as cell}
          <td>
            <FlexRender content={cell.column.columnDef.cell} context={cell.getContext()} />
          </td>
        {/each}
      </tr>
    {/each}
  </tbody>
</table>