Make a HTML content editable in SvelteKit

Make a HTML content editable in SvelteKit

Read if:

  • You wanna learn about SvelteKit and it's features.

Introduction
I know what you thinking, What is this? So, it's started when I was looking for a drag and drop page builder for TailwindCSS. I found one which just allowed me to drag and drop components but editing on the page which made me think of can i do something for problem like this and at the time SvelteKit was released and I noticed one of their features contenteditable.

This feature allows us to edit content on the go without messing with html.You can change content as much as you want.

Here is the Code example : Click here

This is example working Video (Here you will se a changed the text on web and i showed live and with proof in tailwind play).Click Here to watch

How I did it?



<script>
import Clipboard from "svelte-clipboard";

let editableHtml = `
<div class="relative w-full">
    <nav class="fixed z-10 w-full border-b bg-white md:absolute md:bg-transparent">
        <div class="container m-auto px-2 md:px-12 lg:px-7">
            <div class="flex flex-wrap items-center justify-between py-6 gap-6 md:py-4 md:gap-0">
                <div class="w-full px-6 flex justify-between lg:w-max md:px-0">
                    <a href="/" aria-label="logo">
                        <img src="https://tailus.io/sources/blocks/ecommerce-mood/preview/images/logo.svg" class="w-36" alt="tailus logo" width="144" height="68">
                    </a>

                    <button aria-label="humburger" id="hamburger" class="relative w-10 h-10 -mr-2 lg:hidden">
                        <div aria-hidden="true" id="line" class="inset-0 w-6 h-0.5 m-auto rounded bg-gray-500 transtion duration-300"></div>
                        <div aria-hidden="true" id="line2" class="inset-0 w-6 h-0.5 mt-2 m-auto rounded bg-gray-500 transtion duration-300"></div>
                    </button>
                </div>

                <div class="hidden w-full lg:flex flex-wrap justify-between items-center space-y-12 p-6 rounded-xl bg-white md:w-8/12 md:space-y-0 md:p-0 md:flex-nowrap md:bg-transparent lg:w-7/12">
                    <div class="block w-full">
                        <ul class="space-y-12 tracking-wide font-medium md:flex md:space-y-0">
                            <li>
                                <a href="/" class="block md:px-3">
<div class="relative text-cyan-800
            before:absolute before:-bottom-7 before:w-full before:h-0.5 before:mx-auto before:mt-auto before:rounded-full before:bg-cyan-800">
    <span>Nike</span>
</div>
                                </a>
                            </li>
                            <li>
                                <a href="/" class="block md:px-3 group">
                                    <div class="relative text-gray-600
                                                before:absolute before:-bottom-7 before:w-full before:h-0.5 before:mx-auto before:mt-auto before:rounded-full before:bg-cyan-800 before:transition before:scale-x-0 group-hover:before:scale-x-100">
                                        <span class="transition group-hover:text-cyan-700">Adiddas</span>
                                    </div>
                                </a>
                            </li>
                            <li>
                                <a href="/" class="block md:px-3 group">
                                    <div class="relative text-gray-600
                                                before:absolute before:-bottom-7 before:w-full before:h-0.5 before:mx-auto before:mt-auto before:rounded-full before:bg-cyan-800 before:transition before:scale-x-0 group-hover:before:scale-x-100">
                                        <span class="transition group-hover:text-cyan-700">Cart</span>
                                    </div>
                                </a>
                            </li>
                        </ul>
                    </div>

                    <div class="w-full md:w-max">
                        <button type="button" title="Start buying" class="w-full py-3 px-6 text-center rounded-full transition bg-gray-900 hover:bg-cyan-500 active:bg-cyan-600 focus:bg-cyan-800 sm:w-max">
                            <span class="block text-white text-sm">
                                Shop now
                            </span>
                        </button>
                    </div>
                </div>
            </div>
        </div>
    </nav>
    <div class="border-b">
        <div class="container m-auto px-6 pt-24 border-r border-l md:px-12  lg:pt-[4.8rem] lg:px-7">
            <div class="flex items-center flex-wrap gap-12 px-2 md:px-0">
                <div class="lg:w-6/12 lg:-ml-7">
                    <div class="relative">
                        <img src="https://tailus.io/sources/blocks/ecommerce-mood/preview/images/shoes2.jpg" alt="shoes" loading="lazy" width="640" height="640">
                        <div class="absolute bottom-2 right-2 bg-white">
                            <div class="flex p-1">
                                <button aria-label="button-left" class="p-3 border-r">
                                    <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" class="rotate-180 bi bi-chevron-right" fill="currentColor" viewBox="0 0 16 16">
                                        <path fill-rule="evenodd" d="M4.646 1.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1 0 .708l-6 6a.5.5 0 0 1-.708-.708L10.293 8 4.646 2.354a.5.5 0 0 1 0-.708z"/>
                                    </svg>
                                </button>
                                <button aria-label="button-right" class="p-3">
                                    <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-chevron-right" viewBox="0 0 16 16">
                                        <path fill-rule="evenodd" d="M4.646 1.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1 0 .708l-6 6a.5.5 0 0 1-.708-.708L10.293 8 4.646 2.354a.5.5 0 0 1 0-.708z"/>
                                    </svg>
                                </button>
                            </div>
                        </div>
                    </div>
                </div>

                <div class="relative lg:w-6/12 lg:-ml-20">
                    <h1 class="font-bold text-5xl sm:text-6xl md:text-7xl xl:text-8xl">A Look for every <span class="text-cyan-800">mood</span>.</h1>
                    <div class="mt-16 space-y-8 lg:ml-32">
                        <p class="text-gray-700">Sit amet consectetur adipisicing elit. eligendi tenetur nihil quaerat suscipit, sunt dignissimos.</p>
                        <div class="flex space-x-4 ">
                            <button type="button" title="Start buying" class="w-full py-3 px-6 text-center rounded-full transition duration-300 bg-gray-900 hover:bg-cyan-500 active:bg-cyan-600 focus:bg-cyan-800 sm:w-max">
                                <span class="block text-white text-sm">
                                    Shop now
                                </span>
                            </button>
                            <button type="button" title="Start buying" class="w-full py-3 px-6 text-center rounded-full transition border border-gray-200 sm:w-max">
                                <span class="block text-gray-800 text-sm">
                                    View store
                                </span>
                            </button>
                        </div>
                    </div>'
                </div>
            </div>
        </div>
    </div>
</div>`
</script>

<div
    contenteditable="true"
    bind:innerHTML={editableHtml}
></div>

<div class="grid items-center px-20">
<Clipboard
  text={editableHtml}
  let:copy
  on:copy={() => {
    alert('Has Copied');
  }}>
  <button class="my-5 rounded-full px-4 py-2 border border-1 flex justify-center" on:click={copy}>Copy</button>
</Clipboard>
</div>
Enter fullscreen mode Exit fullscreen mode

Now I'll explain the above code.

  • First inside the script tag, I imported Clipboard from the package. I assigned my html to a editableHtml (here I'm Tailus Hero Section).

  • Then i created a div which have contenteditable which made our content editable on webpage and binded our html object editableHtml to innerHTML.

<div
    contenteditable="true"
    bind:innerHTML={editableHtml}
></div>
Enter fullscreen mode Exit fullscreen mode
  • In the end i used Clipboard to copy the changed text to use in my project.

That's it, how you can make a drag and drop website builder for own use so you can have a same kind of template with different data.

This is me writing for you. If you wanna ask or suggest anything please put it in comment.

© 2023 EtherCorps. All rights reserved.