Back

Going from a Canva Design to an Astro Page

Going from a Canva Design to an Astro Page

In this tutorial, we will take a free Canva landing page website template and convert it to an Astro JS landing page.

Canva has many free templates for anything you can think of. We will go for a fitness website and break down each element to recreate in Astro.

When I approach a web development project, whether a website or an application, I find it best to break down what you want to accomplish into smaller steps. I encourage you to do the same. The term modularity categorizes this approach.

Screenshot_2024-02-19-04-46-38-067

Free Canva Template

After reviewing the Canva template, we can see that we need to create six components or modules using Astro.js:

  • Header or Hero Section
  • About Section
  • Offers Section
  • Testimonials
  • Footer

We will also learn how to deploy our website to Netlify via our personal GitHub repository so that you can share your creation with the world.

Sourcing the Images

The best place for placeholder images is Unsplash; this website will keep you current by offering professional-grade images with whatever you type in the search bar.

The one vital detail to be aware of is the Copyright license. The best way to know that the image you want doesn’t need to be credited is by filtering images with the Creative Commons License.

Setting up the project

In this tutorial, we will be using Visual Studio Code, so let’s start by opening the program and then the terminal:

vs1

Once we are in the folder we want to use, we can run the command:

npm create astro@latest

This will start the process of creating our Astro website. You will need to follow the resulting prompts. I am choosing to use the name fitness-astro-landing. You can name the project whatever you like.

Once everything is complete, you will need to run this command:

cd fitness-astro-landing (or your project name)

Next, we will add Tailwind CSS to the project as this will assist us in incorporating our design from the Canva template.

npx astro add tailwind

Again, follow the onscreen prompts, and when they have been completed, we will add our sourced images.

Adding Images

As we are doing a fitness-themed website, we will find the most relevant images for our needs and store them in the public folder.

Github link to images

You must create a folder called images and add the files there.

vs4

Adding the styling and files

Looking at the Canva template, we can see a custom font called “Anton.” Go to the Google Fonts website and get the necessary code to add to the Layouts.astro file, as this file will serve the entire page.

vs3

Open the Layout.astro file and add the following code in the <head> Section. Let us also make the files we decided we needed as components. Navigate to the src/components folder and create the following files:

  • Hero.astro
  • About.astro
  • Offers.astro
  • Testimonials.astro
  • HeroFooter.astro

We will be adding more components later. However, this is what we need to have everything set up; we can now move on to the next step.

Coding the Home page

This is the main file we will use for the entire tutorial. We are using the default Layout.astro file included with the installation. However, we will change the title to reflect our fictional fitness gym name.

Next, we will import each component we made in the components folder to this page.

---
import Layout from '../layouts/Layout.astro';
import Hero from '../components/Hero.astro';
import About from '../components/About.astro';
import Offers from '../components/Offers.astro';
import Testimonials from '../components/Testimonials.astro';
import HeroFooter from '../components/HeroFooter.astro';
---

<Layout title="Astraeus Gym">
 <main>
  <!-- Add Call To action, company Name and Button text2 -->
 <Hero callToAction='Be Your Best', buttonText='Join Today' companyName='Astraeus Gym'/>
 <About linkText="/" imageOne='gym-instructor.jpg', imageTwo='gym-femaleinstructor.jpg' />
 <Offers />
 <Testimonials />
 <HeroFooter callToAction='Get in Touch Today' />
 </main>
</Layout>

Creating the Hero section

vs5

The hero section, or in some terms the jumbotron, is the most important element of this landing page. The reason is because it is the first area users will see. The above image shows the hero section with a background and three other text items:

  • A logo with the brand name
  • A giant call-to-action message
  • A join now button

We will start by making our frontmatter; this is the top area of our Hero.astro page where we can write our Javascript.

We will use Astro props to enable customized changes to the callToAction text. We will also refer to the image we want to use as the background - sourced from Unsplash and stored in the public/images folder.

Here is the finished code:

---
interface Props {
  callToAction: string;
  buttonText: string;
  companyName:string;
  //    logoImage:string;
}
const { callToAction, buttonText, companyName } = Astro.props;

const imageURL = "hero-fitness-image.jpg"
const bgStyle = {
  backgroundImage: `url('/images/${imageURL}')`,
};
---

<header class="bg-cover bg-no-repeat bg-gray-400 bg-blend-multiply" style={bgStyle}>
  <nav class="text-white uppercase pt-8 p-4 font-bold2">
    <ul>
      <li>{companyName}</li>
    </ul>
  </nav>
  <div class="px-4 mx-auto max-w-screen-xl text-center py-36 text-white">
  
      <h1 class="font-extrabold text-9xl tracking-wide mb-4 uppercase italic">{callToAction}</h1>
      <button class="yellowBG p-2 uppercase text-black font-bold">{buttonText}</button>

  </div>
</header>
    
    

Adding the About Section

vs6 In this Section, we can see a two-column layout with a heading and paragraph on one side and images on the other. Let’s break it down:

  • Heading
  • Paragraph
  • link
  • Image links

Now, let’s code the Section in Astro. Open the About.astro file and add the following:

Note: be sure to change the image file names in the index.astro file to match your need.

--- 
interface Props {
  linkText: string;
  imageOne:string;
 imageTwo:string;
}
const { linkText, imageOne, imageTwo } = Astro.props;
---

<section class="py-12">
  <div class="grid grid-cols-2 p-4">
    <div>
      <h1 class="text-white text-5xl italic max-w-xs yellowText pb-8">About Our Fit Family</h1>
      <p class="text-white max-w-sm">
        Astraeus was founded in 2001 by a husband and wife team, Bobby and Dora Graff. Since then, we have expanded to over 115 locations nationwide!
      </p>
      <p class="text-white mt-8 underline">
        <a href={linkText}>Learn more</a>
      </p>
    </div>
    <div class="grid grid-cols-2">
        <img src={'/images/'+imageOne} alt="Gym Instructor" class="rounded-md object-cover w-48"/>
        <img src={'/images/'+imageTwo} alt="Boxing Instructor" class="rounded-md object-cover w-48 pt-8"/>
    </div>
  </div>
</section>

Creating the Offers section

This Section will build on our previous knowledge of adding images and grid layouts. The template shows that this Section consists of three cards with a background image and a bold heading centered inside.

vs7

Let’s make an ImageCard component that will serve as our cards; then, we can iterate the component with custom images and text. Navigate to the src/components and create ImageCard.astro and add the following code:

---
interface Props {
  text: string;
  imageURL: string;
}
const { text = "", imageURL = "" } = Astro.props;
const imageStyle = {
  backgroundImage: `url(/images/${imageURL})`,
};
---

<div
  class="py-48 bg-cover m-8 bg-gray-700 bg-blend-multiply"
  style={imageStyle}
>
  <h2 class="text-white uppercase text-4xl italic">{text}</h2>
</div>

This code will result in a div with the specific background image file and the custom text on the inside. We will be using mapping in Astro JS to make it easier to swap out images and easily change the text.

Now, open the Offers.astro file and import the ImageCard component. Next, we will create an array of objects with the image filename and the text:

    ---
import ImageCard from "./ImageCard.astro";
const offers = [
    {
        imageURL:"dumbbells.jpg",
        offerText:"Tour Our Gym"
    },
    {
        imageURL:"rowing.jpg",
        offerText:"Check out our Group Classes"
    },
    {
        imageURL:"skipping.jpg",
        offerText:"Ask about Personal Training"
    }
]
---

We will first create the Section, heading, and paragraph elements, then we will create our div and use the Astro JS syntax to map over the values:

<section class="py-12 text-center">
<h1 class="yellowText text-5xl italic uppercase">What we offer</h1>
<p class="text-white">We're committed to bringing you the best workout experience</p>
<div class="grid grid-cols-1 md:grid-cols-3">
{
    offers.map((offer)=>(
        <ImageCard imageURL={offer.imageURL} text={offer.offerText} />
    ))
}

</div>
</section>

Adding Testimonials

vs8

This Section is very similar to the Offers section except for the design and text layout.

---
const testimonials = [
  {
    profileURL: "gym-femaleinstructor.jpg",
    author: "Donna Bleaker",
    age: 31,
    quote:
      "Testimonials are short quotes from people who love your brand. It's a great way to convince customers to try your services. ",
  },
  {
    profileURL: "gym-ropes.jpg",
    author: "Lauren Cross",
    age: 28,
    quote:
      "Testimonials are short quotes from people who love your brand. It's a great way to convince customers to try your services. ",
  },
  {
    profileURL: "gym-instructor.jpg",
    author: "Thomas Xue",
    age: 44,
    quote:
      "Testimonials are short quotes from people who love your brand. It's a great way to convince customers to try your services. ",
  },
];
---
<section class="py-12">
  <h1 class="yellowText text-5xl italic uppercase text-center">Before and After</h1>
  <div class="grid grid-cols-1 md:grid-cols-3">
    {
      testimonials.map((profile)=>(
        <div class="m-4">
          <img src={'/images/'+profile.profileURL} alt="Testimonial" class="object-cover w-full h-48"/>
          <div class="yellowBG p-8">
            <p class="pb-4 font-bold">
              {profile.quote}
              </p>
              <small>{profile.author},{profile.age}</small>
            </div>
          </div>

      ))
    }
  </div>
</section>

Looking at the template, we need a profile image of each testimonial, along with their name, age, and comment.

vs9

To finish this landing page, we will take what we learned in the Hero and Testimonial sections and complete the footer design. First, we will create an extra component, the Hero Footer.

Create a HeroFooter.astro file, important the Hero Footer component, and then enter the following:

---
interface Props {
  callToAction: string;
}

const { callToAction } = Astro.props;
const imageURL = "gym-ropes.jpg";
const bgStyle = { backgroundImage: `url('/images/${imageURL}')` };
const content = [
  {
    heading: "Mailing Address",
    info: "123 Anywhere St, Any City, ST 34565",
  },
  {
    heading: "Email Address",
    info: "hello@reallygreatsite.com",
  },
  {
    heading: "Phone Number",
    info: "(123) 456-7890",
  },
];
---

<footer
  class="bg-cover bg-no-repeat bg-gray-700 bg-blend-multiply"
  style={bgStyle}
>
  <div class="mx-auto max-w-screen-xl">
    <h1
      class="font-extrabold text-5xl yellowText tracking-wide uppercase italic p-36 max-w-xl"
    >
      {callToAction}
    </h1>
    <div class="yellowBG grid grid-cols-1 md:grid-cols-3">
      {
        content.map((item) => (
          <div class="p-12">
            <h1 class="uppercase text-2xl italic">{item.heading}</h1>
            <p>{item.info}</p>
          </div>
        ))
      }
    </div>
  </div>
</footer>

View the website locally

With the terminal still running in the background, let’s run the build locally and see the result by running the command:

npm run dev

You can see the finished product when you open your browser to http://localhost:4321.

Screenshot_2024-02-19-04-46-38-067

Live preview of the template

Deploy to Netlify

Watch this YouTube tutorial to learn how to deploy this site to Github and Netlify.

Download the full project source code

Truly understand users experience

See every user interaction, feel every frustration and track all hesitations with OpenReplay — the open-source digital experience platform. It can be self-hosted in minutes, giving you complete control over your customer data. . Check our GitHub repo and join the thousands of developers in our community..

OpenReplay