DEV Community

Cover image for How to Build a Blog Membership Site with Magic Auth and Webflow
Maricris Bonzo for Magic Labs

Posted on • Edited on

How to Build a Blog Membership Site with Magic Auth and Webflow

Hi there đŸ™‹đŸ»â€â™€ïž. In this tutorial we’ll be building a Blog Membership site using Webflow and Magic auth. Webflow will help us design, build and launch responsive websites visually, while Magic will waive its wand to help us create a secure and reliable passwordless login.

đŸ’đŸ»â€â™€ïž Note: This tutorial uses Webflow's Custom Code, which is available on paid Webflow accounts.

alt text

Here’s a Live Demo of the end result!

Magic Setup

  1. Sign up for a Magic account here.
  2. Create a new app and keep this page open (you're going to need the Test Publishable Key in a bit).

Btw, this tutorial uses the email link sign-in method, but you have plenty of other social login options to choose from (Google, GitHub, Facebook, Apple and LinkedIn)! You could also customize the Login form to your liking 😎.

Webflow Setup

  1. Sign up for a Webflow account here.
  2. Create a new project.
  3. Select a Blank Site.
  4. Create your first CMS Collection (this is where you'll be storing your blogs).
    • Choose the ‘Blog Posts’ template.
    • Click ‘Create Collection’ and add 5 sample items.

Create Webflow NavBar Links

Webflow provides you with a Home page by default, so design your navigation bar in there!

Drag and drop a Navbar component, change the background color to white and make sure each of the following links exist:

  1. Home - with an ID of homeLink.
  2. Login - ID: loginLink.
  3. Profile - ID: profileLink.
  4. Log out - ID: logOutLink.

Feel free to add your logo as well.

One more thing; you'll be needing this NavBar in all of your pages, so turn it into a Symbol. This turns the NavBar into a reusable component.

Design & Link Webflow Pages

It's time to design a few pages and link them to your NavBar. Here’s a list of pages you’ll need, each with a step-by-step guide on how to design them.

1. Home

Drag & drop:

  1. A Section, underneath the NavBar, with a margin top and bottom of 50.
  2. A Container on top of the Section.
  3. A Heading on top of the Container, titled “đŸȘ„ Blog Membership Site ✹”.
  4. A Collection List on top of the Container, underneath the title.
    • This Collection List is how you'll be displaying your blog on the homepage. All you need to do is double-click it to connect to the Blog Posts collection you made earlier, and then design it so that it looks like a list of blog posts.
  5. A Heading to one of the Collection items. Make sure to get the Heading’s text from a field in Blog Posts called Name.
  6. A Rich Text field right under the Heading you just added. Make sure you get the text from a field in Blog Posts called Post Body.

By now, you should be able to see all of the blog posts from your CMS Collection!

Lastly, edit the Nav Link Settings for Home such that it has Type: Page, and Page: Home.

2. Login

Drag & drop:

  1. The NavBar Symbol.
  2. A Section, underneath the NavBar, with a margin top and bottom of 50.
  3. A Container on top of the Section.
  4. A Heading on top of the Container, titled “Login 🎉”.
  5. A Form Block on top of the Container, underneath the title.
    • Get rid of the label and text field for the name, you won’t need them.
    • Rename the button to ‘Login’ and give it an ID of loginBtn (Note: The email text field already has an ID of email).

Again, edit the Nav Link Settings for Login such that it has Type: Page, and Page: Login.

3. Profile

Drag & drop:

  1. The NavBar Symbol with a margin top of 50.
  2. A Section, underneath the NavBar, with a margin top and bottom of 50.
  3. A Container on top of the Section.
    • Make sure the Layout > Display of this Container is set to Flex.
  4. Two Headings in the Container.
    • Flex will make it so that they’re positioned right next to each other.
    • The first Heading should read, “Welcome ” while the second Heading reads a temporary text like “user_email”.
    • Add some space between these Headings. Give the second Heading a margin-left of 15.
    • Once the user is logged in, you’ll need to replace “user_email” with the email address they used to log in. To do this, give the second Heading an ID of emailAddress.

Edit the Nav Link Settings for Profile such that it has Type: Page, and Page: Profile.

4. Logout

When the user logs out, they'll need to be routed to the Login page. To do this, edit the Nav Link Settings for Logout such that it has Type: Page, and Page: Login.


Yay you for designing and linking your pages đŸ„ł! Next you’ll learn how to use the Magic SDK to authenticate a user to log in or log out, and protect specific pages.

Write Webflow Site-Wide Custom Code

Webflow's site-wide custom code is applied to your entire site. You’ll be using this option to initialize the Magic SDK, protect certain pages, and allow users to log out.

All you need to do is paste the following code into your Webflow site’s Project Settings > Custom Code.

Head Code

  1. Get the Magic SDK.

    <!-- 1. Get Magic SDK -->
    <script src="https://cdn.jsdelivr.net/npm/magic-sdk/dist/magic.js"></script>
    
  2. Remember that page you left open earlier? Copy the Test Publishable Key from that page and paste it in 'your_test_publishable_key'. This code initializes the Magic SDK.

    <!-- 2. Initialize Magic -->
    <script>
    const magic = new Magic('your_test_publishable_key');
    </script>
    
    

Footer Code

  1. Ensure the logged in user has access to private pages, while the logged out user does not.

    <!-- 4. When the user is logged in/logged out. -->
    <script>
      let privatePages = [
        '/profile',
        '/' // This is where your private blogs live!
      ];
    
      let publicPages = [
        '/login'
      ]
    
      // Get the user & check whether or
      // not the user is logged in. Show or
      // hide pages depending on the outcome.
      const getUser = async () => {
    
        // The page user is currently on
        const currentPath = window.location.pathname;
    
        // Checks if a user is currently logged in
        // to the Magic SDK
        const isLoggedIn = await magic.user.isLoggedIn();
    
        // If the user is logged in...
        if (isLoggedIn) {
    
          // prevent them from accessing public pages.
          if (publicPages.includes(currentPath)) {
            window.location.replace('/');
          } else {
            // Or hide links they don't need to see
            loginLink.style.display = 'none';
          }
        } else {
    
          // If the user is logged out and
          // they try to access a private page,
          // send them back to the login page.
          if (privatePages.includes(currentPath)) {
            window.location.replace('/login');
          } else {
    
            // Or hide links they shouldn't be able to see
            profileLink.style.display = 'none';
            logOutLink.style.display = 'none';
            homeLink.style.display = 'none';
          }
        }
      };
    
      getUser();
    </script>
    
  2. Allow logged in users to log out.

    <!-- 5. Log out the currently authenticated Magic user. -->
    <script>
      const logOut = async () => {
        try {
          await magic.user.logout();
          const isLoggedIn = await magic.user.isLoggedIn();
          console.log('Is the user still logged in? ', isLoggedIn); // => `false`
        } catch (error) {
          // Handle errors if required!
          console.log('Ran into this error while logging out: ', error);
        }
        console.log('WHOO! User has logged out.');
      }
    
      // Call the logOut function when the user
      // clicks the Log Out Nav Link.
      logOutLink.addEventListener('click', logOut);
    </script>
    
    

Write Webflow Page-Only Custom Code

The custom code in a particular page settings only works for that page. You’ll be using this option to implement the login and profile functionalities. Just paste the following code blocks into the appropriate Static Page, inside of the page Settings before the </body> tag.

Log In

Allow the user to log in.

<!-- 3. Log in with Magic Link -->
<script>
  // Log in or create a new user.
  const login = async () => {
    const emailVal = email.value;
    await magic.auth.loginWithMagicLink({
        email: emailVal
      })
      .then(() => {
        // Take user to the home page once they're
        // logged in.
        window.location.replace('./');
      })
      .catch((error) => {
        console.log("Error while logging in: ", error);
      })
  }

  // Call the login function when the user
  // clicks the Login button.
  loginBtn.addEventListener('click', login);
</script>
Enter fullscreen mode Exit fullscreen mode

Profile

Ensure the user’s email is displayed.

<!-- 4. Ensure the user's email is displayed -->
<script type="text/javascript">
  const displayUserName = async () => {
    const {
      email,
      publicAddress
    } = await magic.user.getMetadata();

    let elementToDisplay = document.getElementById('emailAddress');
    elementToDisplay.innerHTML = email;
  }

  displayUserName();
</script>
Enter fullscreen mode Exit fullscreen mode

Test your code

Awesome đŸ€©đŸȘ„! You’ve built a Blog Membership Site. To test the code, you’ll need to publish your site and visit the live url.

Adding a Loader

Have you noticed the lag in the UI when navigating between pages? This happens because the Magic SDK takes a few seconds to initialize. To resolve this, you can add a loader!

  1. Drag & drop a Div Block into your Home page, above the NavBar.
    1. Set it’s Layout > Display to Flex.
    2. Set Align and Justify to Center.
    3. Set it’s Width and Height to 100 VW.
    4. Change it’s background color to a nice contrast to your logo.
  2. Drag & drop an Image onto the Div Block, then upload your loader. It should automatically be centered.
  3. Give the Div Block an ID of loader.
  4. Update the getUser() function in Project Settings > Custom Code > Footer Code:

    const getUser = async () => {
    
        // The page user is currently on
        const currentPath = window.location.pathname;
    
        // Checks if a user is currently logged in
        // to the Magic SDK
        const isLoggedIn = await magic.user.isLoggedIn();
    
        // If the user is logged in...
        if (isLoggedIn) {
    
          // prevent them from accessing public pages.
          if (publicPages.includes(currentPath)) {
            window.location.replace('/');
          } else {
            // Or hide links they don't need to see
            loginLink.style.display = 'none';
            // Get rid of loader when user gets to correct page
            loader.style.display = 'none';
          }
        } else {
    
          // If the user is logged out and
          // they try to access a private page,
          // send them back to the login page.
          if (privatePages.includes(currentPath)) {
            window.location.replace('/login');
          } else {
    
            // Or hide links they shouldn't be able to see
            profileLink.style.display = 'none';
            logOutLink.style.display = 'none';
            homeLink.style.display = 'none';
            // Get rid of loader when user gets to correct page
            loader.style.display = 'none';
          }
        }
      };
    
  5. Turn the Div Block into a Symbol titled, “Loader”.

  6. Drag & drop your Loader Symbol to the rest of the pages.

Publish your changes, and view your live site to see the Loader in action.

That’s it for today!

As you saw, designing a beautiful Blog Membership site with Webflow is easy; just drag and drop elements! Integrating Magic auth into your site for a secure authentication and authorization system was also just as seamless.

Next time you want to build any kind of Membership site with Webflow and Magic auth, this guide will always have your back. Till next time đŸ™‹đŸ»â€â™€ïž.

Top comments (0)