Paytime Documentation

01 · Overview

Introduction

Everything you need to know before you open your editor — what’s in the box, what it’s built with, and what it expects from your machine.

Welcome

Thanks for picking up Paytime. This guide walks through installing the template, understanding how the project is organized, customizing content and styling, and shipping it to production. It’s written for developers who are comfortable with the command line but new to this specific codebase — if you already know Astro well, feel free to skip ahead using the sidebar.

What’s Included

Source files

The full, uncompiled project source — components, pages, styles, and configuration.

Production build script

Run npm run build to generate an optimized, deployable dist/ folder — it isn’t pre-built in the source download.

Image, video & font credits

Full attribution for the Freepik/Unsplash/Pexels imagery and the Outfit and Satoshi typefaces lives on the bundled License page.

This documentation

A single offline HTML file — open it directly in any browser, no server required.

Features

  • A full fintech/payments landing page — hero, feature highlights, an app-tour tab section, a testimonial carousel, tabbed monthly/yearly pricing, and an FAQ accordion, all composed in src/pages/index.astro
  • Smooth, GSAP-powered interactions: an animated FAQ accordion, animated tab panels, a pricing toggle, and a slide-in mobile navigation drawer
  • A dedicated components/style showcase page at /components, plus License, Changelog, and Style Guide utility pages under /template-info/
  • Self-hosted Satoshi font files and the Outfit Google Font, already wired up with @font-face declarations and a <link> tag
  • SEO defaults on every page — canonical URL, Open Graph and Twitter card meta tags, and an auto-generated sitemap via @astrojs/sitemap

Technology Stack

Paytime is built with:

Astro Vanilla JavaScript Vanilla CSS GSAP Swiper

No React, TypeScript, or Tailwind CSS — components are plain .astro files, styling is hand-written CSS, and interactivity is small vanilla-JS modules under src/scripts/.

Requirements

ToolMinimum versionNotes
Node.js22.12.0 or laterMatches the engines.node requirement in package.json
Package managernpm 9+, pnpm 8+, or Yarn 1.22+Use whichever you prefer; examples below cover all three
Code editor—VS Code with the Astro and ESLint extensions is a comfortable default
Git2.xOnly required if you plan to version-control your customized copy

Browser Support

The built site targets the last two versions of all evergreen browsers:

Chrome Firefox Safari Edge
Internet Explorer

Internet Explorer 11 is not supported. No additional polyfills are included.

02 · Setup

Getting Started

From a downloaded ZIP to a running dev server in five steps.

Installation & Extraction

  1. Download the template ZIP from your purchase confirmation email or account downloads page.
  2. Extract it to a folder on your machine — avoid folder names with spaces or special characters.
  3. Open that folder in your terminal and in your code editor.
bash
# Extract on macOS / Linux
unzip paytime-astro.zip -d paytime-astro
cd paytime-astro

Node.js Setup

Check which version of Node.js is currently active:

bash
node --version
# v22.12.0 or later

If you manage multiple Node versions, tools like nvm or fnm make switching painless:

bash
nvm install 22
nvm use 22

Install Dependencies

From the project root, install packages with your preferred package manager:

npm
npm install
pnpm
pnpm install
yarn
yarn install

This reads package.json and downloads every dependency into a local node_modules/ folder. It only needs to be re-run when dependencies change.

Run the Development Server

npm
npm run dev
pnpm
pnpm dev

This starts Astro’s local dev server (powered by Vite) with hot module reloading — edits to components, pages, and styles appear in the browser immediately without a manual refresh. By default it’s available at http://localhost:4321; the terminal output will confirm the exact address.

Build for Production & Preview

bash
# Compile an optimized production build into dist/
npm run build

# Serve that build locally to sanity-check it
npm run preview

build type-checks the project, bundles and minifies assets, and writes static output to dist/. preview serves that exact output locally so you can verify it before deploying — it does not rebuild automatically, so re-run build after further changes.

Which command do I actually need?

Use dev while you’re customizing the template. Use build, then preview, once before you deploy — it catches issues (like a broken import or a missing file) that the dev server tolerates but production won’t.

03 · Reference

Project Structure

A tour of the folders you’ll actually touch, and the ones you generally shouldn’t.

PathPurpose
public/Files here are copied to the output root untouched — no optimization or hashing. Holds images/ (icons, screenshots, favicon), fonts/ (self-hosted Satoshi .otf files), and videos/ (the USP section’s background clip).
src/components/One .astro component per page section — Navbar, Hero, AppFeatures, USP, AppPointsTabs, ReviewSlider, Pricing, FAQ, Footer, ComponentsShowcase.
src/layouts/Layout.astro — the single shared page shell: global <head>/meta/SEO tags and global stylesheet imports. Every page renders through it.
src/pages/Every file here becomes a route automatically. See Pages for details.
src/scripts/Small vanilla-JS modules (accordion.js, tabs.js, smooth-scroll.js, nav-menu.js), several using GSAP, imported directly into a component’s <script> tag.
src/styles/normalize.css, webflow-base.css (layout utility classes from the original Webflow export), and theme.css (color/type tokens and every component’s styles). See Styling.
Files not shown above

_starter/_raw_html/ holds the original Webflow HTML/CSS export this template was converted from. It’s kept for reference only — the live site is built entirely from src/ and doesn’t read from this folder.

04 · Reference

Configuration

The files that control how the project builds, and where to set site-wide values.

package.json

Defines dependencies and the scripts you run from the terminal (dev, build, preview). Add your own script here if you introduce a new tool.

jsonpackage.json
{
  "name": "paytime-astro",
  "version": "1.0.0",
  "engines": { "node": ">=22.12.0" },
  "scripts": {
    "dev": "astro dev",
    "build": "astro build",
    "preview": "astro preview"
  }
}

astro.config.mjs

Controls integrations, the deployed site URL, and build behavior. Paytime registers only the official sitemap integration — there’s no React, Tailwind, or other framework integration to configure.

javascriptastro.config.mjs
import { defineConfig } from 'astro/config';
import sitemap from '@astrojs/sitemap';

export default defineConfig({
  site: 'https://example.com', // used to build absolute URLs for SEO tags and the sitemap
  integrations: [sitemap()],
});
Update the site URL before deploying

The template ships with site: 'https://example.com' as a placeholder. Replace it with your real production domain, or canonical URLs, Open Graph tags, and the generated sitemap will all point at the wrong address.

tsconfig.json

Paytime uses Astro’s default strict preset as-is — there are no custom path aliases configured, so imports use relative paths (e.g. ../../layouts/Layout.astro).

jsontsconfig.json
{
  "extends": "astro/tsconfigs/strict",
  "include": [".astro/types.d.ts", "**/*"],
  "exclude": ["dist"]
}

Environment Variables (.env)

Paytime doesn’t read any environment variables out of the box — there’s no .env file and no API keys to configure. If you add a service that needs one (see API & Data), create a .env file in the project root. Variables must be prefixed PUBLIC_ to be readable in client-side code.

env.env
# Exposed to the browser — never put secrets here
PUBLIC_SITE_URL=https://example.com

# Server-only — safe for secrets, not readable in browser code
API_SECRET_KEY=your_secret_key
Never commit .env

Add .env to .gitignore (it usually is by default). Anything without the PUBLIC_ prefix should stay off the client entirely.

05 · Guide

Pages

How routes are created, and how each page assembles its section components.

Creating a New Page

Astro uses file-based routing: any .astro or .md file placed in src/pages/ automatically becomes a route matching its file path (a .tsx page would additionally require adding the @astrojs/react integration, which this template doesn’t include).

text
src/pages/index.astro       →  /
src/pages/about.astro       →  /about
src/pages/blog/index.astro  →  /blog
src/pages/blog/[slug].astro →  /blog/:slug  (dynamic)

To add a page, create a new file in src/pages/ using the layout and structure of an existing, similar page as a starting point — e.g. src/pages/template-info/license.astro:

astrosrc/pages/services.astro
---
import Layout from '../layouts/Layout.astro';
---
<Layout title="Services - Paytime" description="What we offer.">
  <h1>Our Services</h1>
</Layout>

Editing an Existing Page

Open the relevant file under src/pages/ and edit the markup directly. Anything imported from src/components/ lives elsewhere — edit the component file itself to change content that repeats across multiple pages (like a shared call-to-action block).

Dynamic Routes

Files wrapped in square brackets, such as [slug].astro, generate multiple pages from a single template — commonly used for blog posts or product pages. Astro requires a getStaticPaths() function for these on statically-generated sites. Paytime doesn’t currently ship any dynamic routes (every route under src/pages/ is a fixed, single file), but you can add one the same way in any Astro project:

astrosrc/pages/blog/[slug].astro
---
export async function getStaticPaths() {
  const posts = await import.meta.glob('./posts/*.md');
  return Object.keys(posts).map((path) => ({
    params: { slug: path.split('/').pop().replace('.md', '') },
  }));
}
---

Layouts

Paytime has a single shared layout, src/layouts/Layout.astro, that wraps every page — it imports the three global stylesheets and sets up all SEO/meta tags, then renders page content through a <slot />. Individual pages import their own Navbar and Footer components rather than the layout hard-coding them, so each page controls its own header/footer variant:

astrosrc/layouts/Layout.astro
---
import "../styles/normalize.css";
import "../styles/webflow-base.css";
import "../styles/theme.css";

const {
  title = "Paytime - Astro website template",
  description = "Fastest way to make payment anywhere.",
  noindex = false,
} = Astro.props;
---
<html lang="en">
  <head><title>{title}</title><!-- + SEO meta tags --></head>
  <body class="main-body">
    <slot /> <!-- page supplies its own Navbar / Footer -->
  </body>
</html>

Page Metadata & the 404 Page

Pass title and description props into <Layout> on every page for correct browser tabs and search results (see also SEO); pass noindex to keep a utility page like License or Changelog out of search results. src/pages/404.astro is served automatically whenever no route matches.

06 · Guide

Components

The building blocks pages are assembled from, and how data flows into them.

Reusable Components

Components live in src/components/, one per page section — Hero.astro, AppFeatures.astro, USP.astro, AppPointsTabs.astro, ReviewSlider.astro, Pricing.astro, FAQ.astro, Navbar.astro, Footer.astro, and ComponentsShowcase.astro. Every component is a plain .astro file — there are no .tsx/React components in this template.

Props

Props are the inputs a component accepts, similar to HTML attributes. Paytime doesn’t use TypeScript interface declarations for them — components just destructure Astro.props with a plain default value, which is what most of this template’s components (Navbar, Footer) do for their single page prop:

astrosrc/components/Navbar.astro
---
const { page = "home" } = Astro.props;
---

In plain language: page is optional, and defaults to "home" when the caller doesn’t pass it — used to mark which nav link is aria-current on each page (e.g. <Navbar page="components" /> on /components).

Component Composition

Most sections build their repeating markup by mapping over a small array defined right in the component’s frontmatter, rather than hand-writing each card:

astrosrc/components/AppFeatures.astro
---
const features = [
  { icon: "/images/Billing.svg", title: "Billing", text: "..." },
  { icon: "/images/Invoice.svg", title: "Invoice", text: "..." },
];
---
{features.map((feature) => (
  <div class="feature-block">
    <h3>{feature.title}</h3>
  </div>
))}

Passing Data to Components

In Astro, props are passed the same way as HTML attributes and read via Astro.props. Every page in Paytime passes its own Navbar/Footer a page value so the correct nav link is highlighted:

astrosrc/pages/components.astro
---
import Navbar from '../components/Navbar.astro';
---
<Navbar page="components" />
07 · Guide

Styling

Where to change colors, type, and spacing without fighting the build.

Global Styles & CSS Variables

Color palette and heading font are defined once as CSS custom properties at the top of src/styles/theme.css and referenced everywhere else. Change a value here and it updates across the whole site:

csssrc/styles/theme.css
:root {
  --primary: #502ff5;
  --light-low: #f3f1ff;
  --heading-color: #0f0840;
  --body: #54506f;
  --white: white;
  --orange: #ffb459;
}

Component Styles

Paytime doesn’t use Astro’s scoped <style> blocks. All styling instead lives in three global stylesheets imported once by Layout.astro — normalize.css (browser reset), webflow-base.css (layout utility classes carried over from the original Webflow export), and theme.css (color/type tokens plus every component’s actual styles, keyed by class name, e.g. .pricing-card, .faq-item). To restyle a section, find its class in the markup and edit the matching rule in theme.css.

Responsive Design, Typography & Spacing

Layout switches to a mobile drawer nav and stacked sections at 991px, with further type-size and spacing adjustments at 767px and 479px — all as plain @media (max-width: …) blocks in theme.css. Body copy uses the Outfit Google Font; the self-hosted Satoshi font is used for several heading/UI classes (see Fonts & Icons).

Avoid editing dist/

The dist/ folder is generated output — any change made there is overwritten on the next build. Always edit files under src/.

08 · Guide

Images & Assets

Every image lives in one place, referenced as a plain URL.

LocationUse forBehavior
public/images/All template imagery — hero art, icons, screenshots, the faviconCopied as-is at a fixed URL; no build-time processing (Paytime doesn’t use astro:assets’s <Image> component or a src/assets/ folder)
public/videos/The USP section’s background video (.mp4/.webm) and its poster imageCopied as-is

Replacing Images

Swap the file in public/images/ in place (keeping the same filename), or add a new file and update the src path in the component that references it:

astrosrc/components/Hero.astro
<img
  class="hero-image"
  src="/images/phone.webp"
  alt="Phone frame showing the Paytime app"
  srcset="/images/phone-p-500.png 500w, /images/phone.webp 757w"
  loading="lazy"
/>

Supported Formats & SVGs

The template ships a mix of .webp photography (with a smaller .png fallback in srcset for narrow viewports) and .svg icons, referenced directly as plain <img> sources. If you add a new photo, exporting both a full-size .webp and a smaller fallback keeps the existing responsive pattern consistent.

Image Optimization

There is no build-time image pipeline here — every image is served exactly as it sits in public/images/. Responsive loading instead comes from hand-written srcset/sizes attributes pointing at pre-exported smaller variants (e.g. phone-p-500.png alongside phone.webp). Compress and resize a replacement image yourself before adding it, and export a smaller variant if you want the same responsive behavior.

Rule of thumb

Every image in this template goes in public/images/ (or public/videos/ for video) and is referenced by its root-relative URL — e.g. /images/logo.svg. There is no separate optimized-assets folder to choose between.

09 · Guide

Fonts & Icons

Swapping typefaces and icon sets without touching every component.

Google Fonts

The Outfit font is loaded from Google Fonts via a <link> tag in the shared layout’s <head>. Replace it with your chosen font’s embed code, then update the font-family on body in theme.css:

htmlsrc/layouts/Layout.astro
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link
  href="https://fonts.googleapis.com/css2?family=Outfit:wght@100;200;300;400;500;600;700;800;900&display=swap"
  rel="stylesheet"
/>

Local Fonts

The Satoshi family is self-hosted — five weights of .otf files live in public/fonts/ and are declared with @font-face at the top of src/styles/theme.css, pointing at the root-relative file path:

csssrc/styles/theme.css
@font-face {
  font-family: Satoshi;
  src: url('/fonts/Satoshi-Bold.otf') format("opentype");
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}

Icon Libraries

Paytime doesn’t use an icon component library or sprite sheet. Every icon is an individual .svg file in public/images/ (e.g. check.svg, down-Arrow.svg, the payment-provider marks), referenced directly as a plain <img> source.

Replacing & Adding Icons

Swap the SVG file in public/images/ in place (keeping the filename), or add a new SVG there and point a component’s src at it — there’s no import step or icon registry to update. A few icons are inlined directly as <svg> markup in components (e.g. the footer’s social links in Footer.astro) so they can inherit color via currentColor.

10 · Beginner Friendly

Content Editing

The fastest, lowest-risk way to make the site say what you want it to say.

New to code?

Everything in this section is plain text or attribute changes — no logic to break. Save the file, and your dev server (from Getting Started) will refresh the browser automatically so you can see the change right away.

Headings, Paragraphs & Buttons

Find the relevant component in src/components/ (page copy lives in the component, not the page file — see Pages), locate the text between the tags, and edit it directly:

astrosrc/components/Hero.astro
<!-- before -->
<h1 class="display-title semi-bold">Fastest way to make payment anywhere.</h1>

<!-- after -->
<h1 class="display-title semi-bold">Get paid in seconds, anywhere.</h1>

Menu links live directly in Navbar.astro’s links array; footer copy and social links live directly in Footer.astro — there’s no separate src/data/ file to find. See Navigation for the full pattern.

Cards, Testimonials & Pricing

Repeating content blocks are driven by a plain array declared right in the component’s frontmatter, so adding or removing an item is a matter of editing that list:

astrosrc/components/ReviewSlider.astro
const reviews = [
  { image: "/images/IMG-2.webp", name: "Smith Grey" },
  { image: "/images/IMG.webp", name: "Smith Grey" },
];

Pricing tiers follow the same pattern in Pricing.astro (a plans.monthly / plans.yearly object) and FAQ questions in FAQ.astro (a columnOne / columnTwo array).

Blog Content & Contact Information

Paytime doesn’t include a blog or a contact page. The only contact-adjacent content is the footer’s social links (LinkedIn, Facebook, Twitter/X — currently placeholder URLs) and Play Store link in Footer.astro and Hero.astro; update the hrefs there to point at your real accounts and app listing.

12 · Guide

Forms

Paytime doesn’t ship any forms.

No contact or newsletter form included

There is no <form> anywhere in this template — every call to action (“Get Started”, “Play Store”) is a plain link. If your build needs a contact or signup form, you’ll be adding one from scratch rather than wiring up an existing component.

Contact Forms

Not included. If you add one, a plain HTML <form> with a submit handler is the simplest fit for this template’s vanilla-JS approach (see Third-Party Form Services below for a no-backend option):

html
<form action="[Replace with your form endpoint]" method="POST">
  <input type="email" name="email" required />
  <button type="submit">Submit</button>
</form>

Newsletter Forms

Not included, and not pre-wired to any email provider (Mailchimp, ConvertKit, etc.). Add the provider’s own embed form or hand-roll a form and call their API.

Form Validation

N/A — with no forms in the template, there’s no existing validation to be aware of. If you add a form, standard HTML attributes (required, type="email") cover most cases without writing JavaScript.

Third-Party Form Services

If you’d rather not run your own backend, services like Formspree, Getform, or Basin accept form submissions directly from static HTML and forward them to your email — typically just pointing a form’s action attribute at their endpoint.

13 · Guide

API & Data

Paytime doesn’t fetch data from any external source.

Fully static content

Every number, price, name, and review in this template is a hard-coded value in a component’s frontmatter array (see Content Editing) — there is no fetch() call, API client, or CMS integration anywhere in src/.

API Configuration

N/A. If you wire up a real backend or CMS, read its URL and keys from environment variables rather than hard-coding them (see Configuration):

env.env
PUBLIC_API_URL=https://example.com/api
PUBLIC_API_KEY=your_api_key
Never expose real credentials

The values above are placeholders. Keep real API keys out of version control, and prefer server-only variables (without the PUBLIC_ prefix) for anything sensitive.

Fetch Requests

N/A today. If you add one (e.g. to pull live pricing or reviews), a typical call in an Astro component’s frontmatter looks like:

typescript
const res = await fetch(`${import.meta.env.PUBLIC_API_URL}/products`, {
  headers: { Authorization: `Bearer ${import.meta.env.PUBLIC_API_KEY}` },
});
const data = await res.json();

Data Structures

N/A — every “data structure” in this template is just a plain array of object literals (e.g. Pricing.astro’s plans, ReviewSlider.astro’s reviews) with no TypeScript type declared for their shape.

Error Handling

N/A — with no network requests, there’s nothing to handle errors for. If you add a fetch() call, wrap it so a failed request doesn’t leave a blank section:

typescript
try {
  const res = await fetch(apiUrl);
  if (!res.ok) throw new Error(`Request failed: ${res.status}`);
  const data = await res.json();
} catch (err) {
  // show a fallback UI state instead of a blank page
  console.error(err);
}
14 · Guide

SEO

Per-page metadata, social previews, and the machine-readable files search engines expect.

Page Title & Meta Description

Pass a unique title and description into <Layout> on every page — these drive both the browser tab and the snippet shown in search results:

astro
<Layout
  title="Components - Paytime"
  description="Slightly domed and divided by arches into stiff"
>

Canonical URL, Open Graph & Twitter/X Cards

Set inside Layout.astro’s <head>, using the site value from astro.config.mjs to build absolute URLs. The Open Graph/Twitter image defaults to /images/love-paytime.webp via the layout’s ogImage prop, and can be overridden per page:

htmlsrc/layouts/Layout.astro
<link rel="canonical" href={canonicalURL} />
<meta property="og:title" content={title} />
<meta property="og:description" content={description} />
<meta property="og:image" content={ogImageURL} />
<meta name="twitter:card" content="summary_large_image" />

Sitemap & Robots.txt

The official @astrojs/sitemap integration is already registered in astro.config.mjs and generates sitemap-index.xml automatically at build time once the site value is set to your real domain. There’s no robots.txt in public/ yet — add one pointing at the generated sitemap:

textpublic/robots.txt
User-agent: *
Allow: /
Sitemap: https://example.com/sitemap-index.xml

Structured Data & Semantic HTML

Landmark elements are already in place — each page section is a <section>, the nav bar is a <nav>, and the home page’s single <h1> lives in Hero.astro. There is no JSON-LD structured data in the layout; add it there for rich results (e.g. Organization schema) if you need it.

15 · Guide

Deployment

Platform-by-platform steps. Confirm your rendering mode first — it changes the build output you deploy.

Paytime builds fully static

There’s no adapter registered in astro.config.mjs, so npm run build always produces plain static HTML/CSS/JS in dist/ — any static host works, and none of the SSR-specific notes below apply to this template.

Vercel

  1. Push the project to a GitHub, GitLab, or Bitbucket repository.
  2. In Vercel, choose Add New → Project and import that repository.
  3. Build command: npm run build · Output directory: dist (Astro static) — Vercel’s Astro preset detects this automatically in most cases.
  4. Add any environment variables from your .env file under Project Settings → Environment Variables.
  5. Click Deploy.

Netlify

tomlnetlify.toml
[build]
  command = "npm run build"
  publish = "dist"

Connect the repository in the Netlify dashboard, confirm these build settings, add environment variables under Site configuration → Environment variables, and deploy.

Cloudflare Pages

Connect the repository, set the build command to npm run build and the output directory to dist. For SSR Astro sites, use the official @astrojs/cloudflare adapter instead of the static preset.

GitHub Pages

Set site and base in astro.config.mjs to match your repository URL, then build and publish the dist/ folder to the gh-pages branch (via the official astro build + a deploy action, or manually). GitHub Pages only serves static output — it cannot run an SSR adapter.

Traditional Hosting

Upload the contents of dist/ (after npm run build) to your host’s public web root via FTP/SFTP or your host’s file manager. Since Paytime builds fully static, any plain web host works — no Node process needs to run in production.

16 · Guide

Build & Production

What happens when you run build, and a checklist before you ship.

bash
npm run build     # type-check, bundle, and write dist/
npm run preview   # serve dist/ locally, exactly as it will run in production

Build Output

The build writes static HTML and hashed CSS/JS bundles to dist/. This folder is disposable and regenerated by every build — it’s already excluded from Git via .gitignore.

Environment Variables in Production

N/A for Paytime as shipped — there’s no .env file or environment variable to set (see Configuration). If you add one later, remember each hosting platform requires you to set it again in its own dashboard; a missing production variable is a common cause of a build that works locally but misbehaves once deployed.

Production Checklist

  • Run npm run build locally and confirm it completes with no errors.
  • Run npm run preview and click through the main pages.
  • Confirm the site URL in astro.config.mjs matches your real domain (it ships as https://example.com).
  • Update the placeholder social links in Footer.astro and the Play Store link in Hero.astro/Footer.astro.
  • Verify favicon, Open Graph image, and meta descriptions are your own, not the template defaults.
17 · Reference

Troubleshooting

The most common problems, in the order you’re likely to hit them.

npm install fails

Cause
Node.js version too old, a corrupted local cache, or a stale lockfile from a different package manager.
Solution
Confirm node --version meets the requirement in Requirements, then run rm -rf node_modules package-lock.json && npm install.

Port already in use

Cause
Another process (often a previous dev server that didn’t shut down cleanly) is already listening on the default port.
Solution
Stop the other process, or start this one on a different port: npm run dev -- --port 4322.

Module not found

Cause
A missing dependency, or a typo/casing mismatch in a relative import path (this template has no path aliases configured in tsconfig.json).
Solution
Re-run npm install; check the relative import path (e.g. ../../layouts/Layout.astro) matches the file’s real location and casing exactly.

Images not loading

Cause
An incorrect path in an <img src>. All images in this template live in public/images/ (or public/videos/), referenced by root-relative URL — there’s no src/assets/ import step to get wrong.
Solution
Review Images & Assets — confirm the file exists under public/images/ and the src matches its filename exactly, including case.

Styles not loading

Cause
One of the three global stylesheets isn’t imported into Layout.astro, or the class name in your markup doesn’t match the selector in theme.css.
Solution
Confirm normalize.css, webflow-base.css, and theme.css are all imported at the top of Layout.astro; search theme.css for the exact class name you expect to apply.

TypeScript / build type errors

Cause
Paytime has no .tsx components or declared prop interfaces, so this is rare — it’s usually a plain syntax mistake in a component’s frontmatter (between the --- fences) surfacing under Astro’s strict tsconfig preset.
Solution
Read the error’s file and line number and check the frontmatter syntax there — a missing comma, an unclosed brace, or a variable used before it’s defined are the most common culprits.

Build fails (but dev server works)

Cause
The dev server is more forgiving than build, which fully type-checks the project — an issue tolerated in dev can fail the build.
Solution
Read the full terminal output for the first error (later errors are often side effects of it); fix issues top to bottom and re-run.

Environment variables not working

Cause
Paytime doesn’t read any .env variables out of the box, so this only applies once you’ve added your own (see Configuration). The usual cause is a missing PUBLIC_ prefix for a client-side value, or not restarting the dev server after editing .env.
Solution
Rename the variable with the PUBLIC_ prefix if it’s used in browser code, then stop and restart npm run dev — env changes aren’t hot-reloaded.

Deployment problems

Cause
Wrong output directory configured on the host, or environment variables set locally but not in the platform’s dashboard.
Solution
Re-check the build command and output folder against Deployment for your platform, and confirm every variable from .env is duplicated there.
18 · Reference

FAQ

Quick answers to the questions we hear most.

How do I install the template?

Extract the ZIP, run your package manager’s install command, then start the dev server. The full walkthrough is in Getting Started.

Which Node.js version should I use?

Node 22.12.0 or later — see Requirements. This matches the engines.node field in package.json.

Does this template use TypeScript or React?

No — every component is a plain .astro file with vanilla-JS interactivity (some of it GSAP-powered). tsconfig.json is present only because Astro projects ship one by default; see Technology Stack.

How do I change colors?

Update the CSS custom properties at the top of src/styles/theme.css — see Styling.

How do I change fonts?

Swap the Google Fonts <link> in Layout.astro (for Outfit) or the @font-face files in public/fonts/ (for Satoshi) — see Fonts & Icons.

How do I replace images?

Swap the file in public/images/ or update the src path that points to it — see Images & Assets.

How do I add a new page?

Add a file to src/pages/; the route is created automatically — see Pages.

How do I deploy the template?

Platform-specific steps for Vercel, Netlify, Cloudflare Pages, GitHub Pages, and traditional hosts are in Deployment.

Can I use the template commercially?

[State your license terms here — e.g. standard vs. extended license — and link to the full license text.]

Where can I get support?

See the Support section for contact details and what to include in a request.

19 · Reference

Changelog

Every notable change, newest first. Add a new entry above the last one for each release.

Version 1.0.0
  • AddedInitial release.
Keeping this current

Copy the markup for one entry above, update the version number, date, and bullet list, and place it at the top of this section for each new release.

20 · Reference

Support

Stuck on something this guide didn’t cover? Here’s how to reach us.

Documentation

Most questions are answered somewhere in this guide — try the search (Ctrl K) before reaching out.

Back to top

Contact support

Email hello@rnnstudio.com or reach us through our contact form.

Contact support

Support hours

We’re based in India and available Monday–Friday, 10am–7pm IST. Expect a response within 24 hours.

What to Include in a Support Request

The fastest way to get a useful answer is to include the details below in your first message:

text
When contacting support, please include:

- Template name and version
- Browser (and version)
- Operating system
- Node.js version (node --version)
- The exact error message
- Steps to reproduce the problem