gettickr
Home
Features
PricingHelp
Getting Started
What is gettickr.app?
Free vs. Premium
Create Account
Timer Configuration
Create Countdown (Duration)
Create CountTo (Date)
Customize Design
Preview vs. Renderer
Save & Manage Timers
Remote Control
Streaming Integration
Streaming Platforms Overview
OBS Studio Integration
Streamlabs Integration
XSplit Integration
Website Integration
Website Integration Overview
iFrame Integration
WordPress Integration
Shopify Integration
Wix / Squarespace
Custom HTML Websites
Advanced Features
Timer State & Persistence
Free vs. Premium Timers
FAQ & Troubleshooting
Common Questions
Known Issues
Contact Support
Help Center
/
Website Integration
/
Custom HTML Integration

Table of Contents

Quick Start OverviewBasic HTML IntegrationCSS Styling and LayoutStatic Site GeneratorsFramework IntegrationPerformance OptimizationSecurity Best PracticesTroubleshootingNext Steps

Custom HTML Websites

Information
Custom-coded websites offer complete control over timer integration. Whether you're working with pure HTML, using a static site generator, or building with a framework, this guide covers everything you need!

Custom-coded websites offer unlimited flexibility for embedding gettickr.app timers. This guide is designed for developers and covers integration methods from basic HTML to advanced framework implementations.

Quick Start Overview

ImplementationDifficultyBest ForTime Required
Basic HTMLEasyStatic sites2 minutes
Responsive CSSEasyMobile-friendly sites5 minutes
JavaScriptMediumDynamic loading10 minutes
Static BuildersMediumJAMstack sites5 minutes
React/VueMediumSPAs, modern apps10 minutes
AdvancedHardComplex integrations30+ minutes
Tip
Start with basic HTML integration and progressively enhance based on your specific needs and site architecture!

Basic HTML Integration

The simplest integration method uses a standard HTML iFrame element.

Minimal Implementation

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Event Countdown</title>
  </head>
  <body>
    <h1>Product Launch Countdown</h1>

    <iframe
      src="https://gettickr.app/r/#YOUR-TIMER-ID"
      width="800"
      height="400"
      frameborder="0"
      title="Launch Countdown Timer"
    >
    </iframe>

    <p>Don't miss our biggest launch of the year!</p>
  </body>
</html>

HTML Attributes Reference

AttributeRequiredExample ValuePurpose
src✅ Yeshttps://gettickr.app/r/#abc123Timer URL
width✅ Yes800 or 100%iFrame width
height✅ Yes400iFrame height
frameborder⬜ No0Remove border (legacy)
style⬜ Noborder: none;CSS styling
title⬜ Yes"Countdown Timer"Accessibility description
aria-label⬜ No"Time remaining: 3 hours"Screen reader description
loading⬜ NolazyLazy loading
allow⬜ NofullscreenFeature permissions
sandbox⬜ Noallow-scripts allow-same-originSecurity restrictions
referrerpolicy⬜ Nono-referrer-when-downgradeReferrer header policy

CSS Styling and Layout

Centered Timer

<style>
  .timer-container {
    max-width: 1200px;
    margin: 0 auto;
    padding: 20px;
    text-align: center;
  }

  .timer-container iframe {
    display: block;
    margin: 0 auto;
    border: none;
    box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
    border-radius: 8px;
  }
</style>
<div class="timer-container">
  <h2>Event Countdown</h2>
  <iframe
    src="https://gettickr.app/r/#YOUR-TIMER-ID"
    width="100%"
    height="400"
    title="Event Timer"
  >
  </iframe>
</div>

Grid Layout with Multiple Timers

<style>
  .timer-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(400px, 1fr));
    gap: 30px;
    padding: 20px;
    max-width: 1400px;
    margin: 0 auto;
  }

  .timer-card {
    background: #f8f9fa;
    border-radius: 12px;
    padding: 30px;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
  }

  .timer-card h3 {
    margin-top: 0;
    color: #333;
  }

  .timer-card iframe {
    width: 100%;
    border: none;
    border-radius: 8px;
  }
</style>

<div class="timer-grid">
  <div class="timer-card">
    <h3>Event 1: Product Launch</h3>
    <iframe
      src="https://gettickr.app/r/#TIMER-1"
      height="300"
      title="Event 1 Timer"
    ></iframe>
  </div>

  <div class="timer-card">
    <h3>Event 2: Flash Sale</h3>
    <iframe
      src="https://gettickr.app/r/#TIMER-2"
      height="300"
      title="Event 2 Timer"
    ></iframe>
  </div>

  <div class="timer-card">
    <h3>Event 3: Webinar</h3>
    <iframe
      src="https://gettickr.app/r/#TIMER-3"
      height="300"
      title="Event 3 Timer"
    ></iframe>
  </div>
</div>

Hero Section Timer

<style>
  .hero-countdown {
    background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
    color: white;
    padding: 80px 20px;
    text-align: center;
    position: relative;
    overflow: hidden;
  }

  .hero-countdown::before {
    content: '';
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background: url('/pattern.svg') repeat;
    opacity: 0.1;
  }

  .hero-countdown .content {
    position: relative;
    z-index: 1;
    max-width: 1200px;
    margin: 0 auto;
  }

  .hero-countdown h1 {
    font-size: 56px;
    margin: 0 0 20px 0;
    font-weight: 700;
  }

  .hero-countdown .subtitle {
    font-size: 24px;
    margin: 0 0 40px 0;
    opacity: 0.95;
  }

  .hero-countdown iframe {
    border: none;
    background: transparent;
    max-width: 100%;
  }
</style>

<section class="hero-countdown">
  <div class="content">
    <h1>🎉 Grand Opening Sale</h1>
    <p class="subtitle">Up to 70% Off - Don't Miss Out!</p>
    <iframe
      src="https://gettickr.app/r/#YOUR-TIMER-ID"
      width="100%"
      height="500"
      title="Sale Countdown"
    >
    </iframe>
  </div>
</section>

Static Site Generators

Jekyll

<!-- _includes/countdown-timer.html -->
<div class="countdown-timer-wrapper">
  {% if include.title %}
  <h2>{{ include.title }}</h2>
  {% endif %}

  <iframe
    src="https://gettickr.app/r/#{{ include.timer_id }}"
    width="{{ include.width | default: '100%' }}"
    height="{{ include.height | default: '400' }}"
    frameborder="0"
    style="border: none; max-width: 100%;"
    title="{{ include.title | default: 'Countdown Timer' }}"
  >
  </iframe>

  {% if include.caption %}
  <p class="timer-caption">{{ include.caption }}</p>
  {% endif %}
</div>

<!-- Usage in pages/posts -->
{% include countdown-timer.html timer_id="YOUR-TIMER-ID" title="Event Countdown"
height="500" caption="Don't miss out!" %}

Hugo

<!-- layouts/shortcodes/timer.html -->
{{ $timerId := .Get "id" }} {{ $width := .Get "width" | default "100%" }} {{
$height := .Get "height" | default "400" }} {{ $title := .Get "title" | default
"Countdown Timer" }}

<div class="hugo-timer-container">
  {{ if .Get "heading" }}
  <h2>{{ .Get "heading" }}</h2>
  {{ end }}

  <iframe
    src="https://gettickr.app/r/#{{ $timerId }}"
    width="{{ $width }}"
    height="{{ $height }}"
    frameborder="0"
    style="border: none; max-width: 100%;"
    title="{{ $title }}"
  >
  </iframe>
</div>

<!-- Usage in content files -->
{{< timer id="YOUR-TIMER-ID" height="500" heading="Sale Ends Soon!" >}}

Gatsby (React)

// src/components/CountdownTimer.js
import React from 'react';

const CountdownTimer = ({
  timerId,
  width = '100%',
  height = '400',
  title = 'Countdown Timer',
  className = '',
  style = {}
}) => {
  if (!timerId) {
    console.error('CountdownTimer: timerId prop is required');
    return null;
  }

  const iframeStyle = {
    border: 'none',
    maxWidth: '100%',
    ...style
  };

  return (
    <iframe
      src={`https://gettickr.app/r/#${timerId}`}
      width={width}
      height={height}
      title={title}
      className={className}
      style={iframeStyle}
      frameBorder="0"
      allowFullScreen
    />
  );
};

export default CountdownTimer;

// Usage in pages
import CountdownTimer from '../components/CountdownTimer';

const EventPage = () => (
  <div>
    <h1>Product Launch</h1>
    <CountdownTimer
      timerId="YOUR-TIMER-ID"
      height="500"
      title="Launch Countdown"
    />
  </div>
);

Eleventy (11ty)

// _includes/timer.njk
<div class="eleventy-timer">
  {% if heading %}
  <h2>{{ heading }}</h2>
  {% endif %}

  <iframe
    src="https://gettickr.app/r/#{{ timerId }}"
    width="{{ width or '100%' }}"
    height="{{ height or '400' }}"
    frameborder="0"
    style="border: none; max-width: 100%;"
    title="{{ title or 'Countdown Timer' }}"
  >
  </iframe>
</div>

<!-- Usage in templates -->
{% include "timer.njk", { timerId: "YOUR-TIMER-ID", heading: "Event Countdown",
height: "500" } %}
Tip
Create reusable timer components/includes in your static site generator to maintain consistency and simplify timer management across your site!

Framework Integration

React Component

import React, { useEffect, useRef, useState } from 'react';

const TickrTimer = ({
  timerId,
  width = '100%',
  height = '400',
  title = 'Countdown Timer',
  className = '',
  loading = 'lazy',
  onLoad,
  onError
}) => {
  const iframeRef = useRef(null);
  const [isLoaded, setIsLoaded] = useState(false);
  const [hasError, setHasError] = useState(false);

  useEffect(() => {
    const iframe = iframeRef.current;
    if (!iframe) return;

    const handleLoad = () => {
      setIsLoaded(true);
      onLoad?.();
    };

    const handleError = () => {
      setHasError(true);
      onError?.();
    };

    iframe.addEventListener('load', handleLoad);
    iframe.addEventListener('error', handleError);

    return () => {
      iframe.removeEventListener('load', handleLoad);
      iframe.removeEventListener('error', handleError);
    };
  }, [onLoad, onError]);

  if (!timerId) {
    console.error('TickrTimer: timerId prop is required');
    return <div>Error: Timer ID not provided</div>;
  }

  return (
    <div className={`tickr-timer-wrapper ${className}`}>
      {!isLoaded && !hasError && (
        <div className="timer-loading">Loading timer...</div>
      )}
      {hasError && (
        <div className="timer-error">Failed to load timer</div>
      )}
      <iframe
        ref={iframeRef}
        src={`https://gettickr.app/r/#${timerId}`}
        width={width}
        height={height}
        title={title}
        loading={loading}
        style={{ border: 'none', maxWidth: '100%' }}
        frameBorder="0"
        allowFullScreen
      />
    </div>
  );
};

export default TickrTimer;

// Usage
import TickrTimer from './components/TickrTimer';

function App() {
  return (
    <div>
      <h1>Product Launch</h1>
      <TickrTimer
        timerId="YOUR-TIMER-ID"
        height="500"
        className="launch-timer"
        onLoad={() => console.log('Timer loaded')}
      />
    </div>
  );
}

Vue 3 Component

<!-- CountdownTimer.vue -->
<template>
  <div class="countdown-timer-wrapper" :class="className">
    <div v-if="loading && !loaded" class="timer-loading">
      Loading timer...
    </div>
    <div v-if="error" class="timer-error">
      Failed to load timer
    </div>
    <iframe
      ref="iframeRef"
      :src="`https://gettickr.app/r/#${timerId}`"
      :width="width"
      :height="height"
      :title="title"
      :loading="loadingAttr"
      frameborder="0"
      allowfullscreen
      style="border: none; max-width: 100%;"
      @load="handleLoad"
      @error="handleError"
    />
  </div>
</template>

<script setup>
import { ref, onMounted } from 'vue';

const props = defineProps({
  timerId: {
    type: String,
    required: true
  },
  width: {
    type: String,
    default: '100%'
  },
  height: {
    type: String,
    default: '400'
  },
  title: {
    type: String,
    default: 'Countdown Timer'
  },
  className: {
    type: String,
    default: ''
  },
  loadingAttr: {
    type: String,
    default: 'lazy'
  }
});

const emit = defineEmits(['load', 'error']);

const iframeRef = ref(null);
const loaded = ref(false);
const error = ref(false);
const loading = ref(true);

const handleLoad = () => {
  loaded.value = true;
  loading.value = false;
  emit('load');
};

const handleError = () => {
  error.value = true;
  loading.value = false;
  emit('error');
};
</script>

<style scoped>
.countdown-timer-wrapper {
  position: relative;
}

.timer-loading,
.timer-error {
  padding: 20px;
  text-align: center;
  background: #f0f0f0;
  border-radius: 8px;
}

.timer-error {
  color: #e74c3c;
}
</style>

<!-- Usage -->
<template>
  <div>
    <h1>Event Countdown</h1>
    <CountdownTimer
      timer-id="YOUR-TIMER-ID"
      height="500"
      @load="onTimerLoad"
    />
  </div>
</template>

<script setup>
import CountdownTimer from './components/CountdownTimer.vue';

const onTimerLoad = () => {
  console.log('Timer loaded successfully');
};
</script>

Angular Component

// countdown-timer.component.ts
import { Component, Input, OnInit } from '@angular/core';
import { DomSanitizer, SafeResourceUrl } from '@angular/platform-browser';

@Component({
  selector: 'app-countdown-timer',
  template: `
    <div class="countdown-timer-wrapper" [ngClass]="className">
      <div *ngIf="loading" class="timer-loading">Loading timer...</div>
      <div *ngIf="error" class="timer-error">Failed to load timer</div>
      <iframe
        [src]="safeUrl"
        [width]="width"
        [height]="height"
        [title]="title"
        [attr.loading]="loadingAttr"
        frameborder="0"
        allowfullscreen
        (load)="onLoad()"
        (error)="onError()"
        style="border: none; max-width: 100%;">
      </iframe>
    </div>
  `,
  styles: [`
    .countdown-timer-wrapper {
      position: relative;
    }
    .timer-loading, .timer-error {
      padding: 20px;
      text-align: center;
      background: #f0f0f0;
      border-radius: 8px;
    }
    .timer-error {
      color: #e74c3c;
    }
  `]
})
export class CountdownTimerComponent implements OnInit {
  @Input() timerId!: string;
  @Input() width: string = '100%';
  @Input() height: string = '400';
  @Input() title: string = 'Countdown Timer';
  @Input() className: string = '';
  @Input() loadingAttr: string = 'lazy';

  safeUrl!: SafeResourceUrl;
  loading: boolean = true;
  error: boolean = false;

  constructor(private sanitizer: DomSanitizer) {}

  ngOnInit() {
    if (!this.timerId) {
      console.error('CountdownTimer: timerId is required');
      this.error = true;
      this.loading = false;
      return;
    }

    const url = `https://gettickr.app/r/#${this.timerId}`;
    this.safeUrl = this.sanitizer.bypassSecurityTrustResourceUrl(url);
  }

  onLoad() {
    this.loading = false;
  }

  onError() {
    this.loading = false;
    this.error = true;
  }
}

// Usage in templates
<app-countdown-timer
  timerId="YOUR-TIMER-ID"
  height="500"
  className="launch-timer">
</app-countdown-timer>
Information
Framework components provide better integration with your app's lifecycle, state management, and can include loading states and error handling.

Performance Optimization

Lazy Loading

<iframe
  src="https://gettickr.app/r/#YOUR-TIMER-ID"
  width="100%"
  height="400"
  loading="lazy"
  style="border: none;"
  title="Countdown Timer"
>
</iframe>

Preload Critical Timers

<!-- In <head> section -->
<link rel="preconnect" href="https://gettickr.app" />
<link rel="dns-prefetch" href="https://gettickr.app" />

Async Loading Script

<div id="timer-placeholder" data-timer-id="YOUR-TIMER-ID"></div>

<script>
  (function () {
    function loadTimer() {
      const placeholder = document.getElementById('timer-placeholder');
      const timerId = placeholder.dataset.timerId;

      if (!placeholder || !timerId) return;

      const iframe = document.createElement('iframe');
      iframe.src = `https://gettickr.app/r/#${timerId}`;
      iframe.width = '100%';
      iframe.height = '400';
      iframe.style.border = 'none';
      iframe.title = 'Countdown Timer';

      placeholder.appendChild(iframe);
    }

    // Load after page is fully loaded
    if (document.readyState === 'complete') {
      loadTimer();
    } else {
      window.addEventListener('load', loadTimer);
    }
  })();
</script>

Performance Best Practices

PracticeImplementationBenefit
Lazy LoadingAdd loading="lazy" attributeFaster initial page load
DNS Prefetch<link rel="dns-prefetch">Faster connection
Preconnect<link rel="preconnect">Faster resource loading
Async JavaScriptLoad after page load eventNon-blocking load
Intersection ObserverLoad when scrolling into viewDeferred loading
Minimize Timer Count1-3 timers per page maxBetter performance
Appropriate DimensionsMatch design sizeReduce unnecessary render
Remove Unused AttributesStrip unnecessary HTMLSmaller DOM

Security Best Practices

Content Security Policy (CSP)

<!-- Add to <head> or set as HTTP header -->
<meta
  http-equiv="Content-Security-Policy"
  content="default-src 'self'; frame-src https://gettickr.app; script-src 'self';"
/>

Sandbox Attribute (if required)

<iframe
  src="https://gettickr.app/r/#YOUR-TIMER-ID"
  width="100%"
  height="400"
  sandbox="allow-scripts allow-same-origin"
  title="Countdown Timer"
>
</iframe>
Warning
Only use sandbox attribute if specifically required by your security policy. Incorrect configuration can break timer functionality.

HTTPS Only

<iframe
  src="https://gettickr.app/r/#YOUR-TIMER-ID"
  width="100%"
  height="400"
  title="Countdown Timer"
>
</iframe>
Information
Always use HTTPS (https://) in timer URLs, never HTTP. Modern browsers block mixed content (HTTP iFrames on HTTPS pages).

Troubleshooting

Common Issues

ProblemPossible CauseSolution
Timer not appearingIncorrect URLVerify timer ID and URL
Black/blank iframeNetwork issueCheck browser console for errors
Content Security PolicyCSP blocking iframeAdd gettickr.app to frame-src
Mixed content warningHTTP on HTTPS pageUse https:// in timer URL
Timer too smallContainer size too smallAdjust container width/height
Overlapping contentCSS conflictsUse isolation or z-index
Slow loadingNo lazy loadingAdd loading="lazy" attribute
JavaScript errorsSyntax error in codeCheck browser console, validate JS

Next Steps

  • iFrame Integration - Basic iFrame documentation
  • WordPress Integration - If also using WordPress
  • Shopify Integration - For e-commerce sites
    Tip
    Custom HTML integration offers maximum flexibility. Start simple and progressively enhance based on your needs!
2026|Made by
ChangelogLegal NoticePrivacy PolicyCookie PolicyTerms