Route as modal in Sapper
Asked Answered
G

1

6

I am trying to implement in Sapper what is done in the next.js example called with-route-as-modal.

What it does is that when clicking on a link, the new page is shown in a modal instead of replacing the current page, and the URL is updated, reflecting current modal page. It is implemented in several social networks, such as instagram.

In the next.js example, it is done by using a dynamic href, like this :

<Link href={`/?postId=${id}`} as={`/post/${id}`}>

How can I implement it in Sapper ?

Thanks for your time.

Guttate answered 13/4, 2020 at 9:39 Comment(0)
G
1

I managed to do it in this way :

<script>
  import { prefetch } from '@sapper/app'
  import { onMount, onDestroy } from 'svelte'
  import Post from '../components/Post.svelte'

  let props

  onMount(() => {
    window.onpopstate = function (event) {
      if (document.location.pathname === '/about') {
        props = null
      } else {
        const regex = /\/blog\/([\w-]+)/
        if (regex.test(document.location.pathname)) {
          handlePrefetch(document.location.pathname)
        }
      }
    }

    return () => {
      window.onpopstate = null
    }
  })

  function handleClick(event) {
    event.preventDefault()
    const clickedHref = event.currentTarget.href
    if (clickedHref === location.href) return

    const pathname = clickedHref.replace(location.origin, '').substring(1)
    history.pushState(null, '', pathname)
    handlePrefetch(pathname)
  }

  async function handlePrefetch(url) {
    const res = await prefetch(url)
    const { branch } = res
    props = branch[1].props.post
  }

  function handleClose() {
    history.pushState(null, '', 'about')
    props = null
  }
</script>

<svelte:head>
  <title>About</title>
</svelte:head>

<h1>About this site</h1>

<p>This is the 'about' page. There's not much here.</p>

<a href="/blog/what-is-sapper" on:click="{handleClick}">lien ici</a>

{#if props}
<Post title="{props.title}" html="{props.html}"></Post>
<button on:click="{handleClose}"></button>
{/if}

I had to handle the pop state event manually (so that back button still works). I then used sapper prefetch function and inject resulting props as local props. Then I check if any props are set, and then inject custom HTML depending on it.

The "real page" is just a sapper component that contains <Post title={post.title} html={post.html} />

Guttate answered 10/9, 2020 at 14:43 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.