JavaScript - Managing JavaScript files

Modified on Thu, 4 Dec at 11:34 AM

JavaScript - Managing JavaScript files

JavaScript files in Hubhus allow you to create reusable JavaScript code that can be referenced across multiple web pages, forms, and templates.

On this page

Jump to any section using the links below

JavaScript files in Hubhus allow you to create reusable JavaScript code that can be referenced across multiple web pages, forms, and templates. JavaScript files are hosted on public URLs with browser caching for optimal performance.


What are JavaScript files

JavaScript files are:

  • Reusable JavaScript code stored centrally
  • Accessible via public URLs
  • Cached in browsers for performance (default 600 seconds)
  • Referenced via <script> tags
  • Used across web pages, forms, layouts, and components

This allows you to:

  • Add interactive functionality to pages
  • Maintain consistent behavior across all pages
  • Update scripts in one place and affect all pages
  • Improve page load times with browser caching
  • Separate functionality from HTML structure

Accessing JavaScript files

Go to Account → Web Resources → JavaScript

When you first open this section, you'll see:

"JavaScript files on publicly available URLs."

"There are no JavaScript files. Click "New JavaScript File" to add one."

Click + New JavaScript File to create your first JavaScript file.


Creating a new JavaScript file

Click + New JavaScript File to open the creation dialog.


JavaScript file configuration

Name: Give your JavaScript file a descriptive name (e.g., "Form validation", "Analytics tracking", "Interactive features")

This is for your reference and doesn't appear in the URL.

Browser cache for (seconds): Set how long browsers should cache the JavaScript file (default: 600 seconds = 10 minutes)

  • Shorter cache (60-300 seconds): Changes appear faster, but more server requests
  • Longer cache (600-3600 seconds): Better performance, but changes take longer to appear
  • Very long cache (86400+ seconds): Best performance for rarely-changing scripts

JavaScript code editor: Add your JavaScript code without <script> tags.

Example:

javascript
// Add JavaScript code here without <script>-tags

// Form validation
function validateEmail(email) {
    const regex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
    return regex.test(email);
}

// Smooth scroll to element
function scrollToElement(elementId) {
    const element = document.getElementById(elementId);
    if (element) {
        element.scrollIntoView({ behavior: 'smooth' });
    }
}

// Initialize on page load
document.addEventListener('DOMContentLoaded', function() {
    console.log('JavaScript loaded successfully');
    
    // Add event listeners
    const submitButton = document.getElementById('submit-btn');
    if (submitButton) {
        submitButton.addEventListener('click', handleSubmit);
    }
});

function handleSubmit(event) {
    event.preventDefault();
    
    const emailInput = document.getElementById('email');
    if (emailInput && !validateEmail(emailInput.value)) {
        alert('Please enter a valid email address');
        return false;
    }
    
    // Submit form logic here
    console.log('Form submitted');
}

Click + Create to save the JavaScript file.


JavaScript file list view

After creating JavaScript files, the list shows:

  • Name: File identifier
  • Slug: URL path component (auto-generated from name)
  • URL: Full public link with <script> tag code
  • Placeholders: Placeholder references for templates
  • Caching: Browser cache duration
  • Edit/Delete: Management buttons

Using JavaScript files in web pages

After creating a JavaScript file, reference it in your web pages.

Method 1: Using the public URL script tag

Copy the <script> tag from the URL column (format similar to CSS):

html
<script src="https://leadvalidator.dk/js/yourcompany/form-validation.js"></script>

Place it in your web page HTML, typically before the closing </body> tag:

html
<!DOCTYPE html>
<html lang='en'>
<head>
    <meta charset="UTF-8">
    <title>My Page</title>
</head>
<body>
    <div class="container">
        <h1>Contact Form</h1>
        <form id="contact-form">
            <input type="email" id="email" placeholder="Your email">
            <button type="submit" id="submit-btn">Submit</button>
        </form>
    </div>
    
    <!-- Load JavaScript at end of body for better performance -->
    <script src="https://leadvalidator.dk/js/yourcompany/form-validation.js"></script>
</body>
</html>

Method 2: Using placeholders (similar to CSS)

The Placeholders column shows placeholder options:

@javascript[slug,tag] - Generates full <script> tag:

html
@javascript[form-validation,tag]

Outputs:

html
<script src="https://leadvalidator.dk/js/yourcompany/form-validation.js"></script>

@javascript[slug,url] - Generates URL only:

html
<script src="@javascript[form-validation,url]"></script>

@javascript[slug,body] - Inlines JavaScript content:

html
<script>
@javascript[form-validation,body]
</script>

Script placement best practices

Before closing </body> tag (recommended):

html
<body>
    <!-- Page content -->
    
    <script src="@javascript[your-script,url]"></script>
</body>

Benefits:

  • Page content loads first (better perceived performance)
  • DOM elements exist when script runs
  • No blocking of page rendering

In <head> with defer attribute:

html
<head>
    <script src="@javascript[your-script,url]" defer></script>
</head>

Benefits:

  • Script downloads in parallel with page parsing
  • Executes after DOM is ready
  • Maintains execution order

In <head> with async attribute:

html
<head>
    <script src="@javascript[your-script,url]" async></script>
</head>

Benefits:

  • Script downloads and executes as soon as available
  • Doesn't block page parsing
  • Use for independent scripts (analytics, ads)

Common JavaScript patterns

Form validation:

javascript
document.addEventListener('DOMContentLoaded', function() {
    const form = document.getElementById('contact-form');
    
    if (form) {
        form.addEventListener('submit', function(event) {
            event.preventDefault();
            
            const email = document.getElementById('email').value;
            const name = document.getElementById('name').value;
            
            if (!email || !name) {
                alert('Please fill in all required fields');
                return false;
            }
            
            if (!validateEmail(email)) {
                alert('Please enter a valid email address');
                return false;
            }
            
            // Submit form
            form.submit();
        });
    }
});

function validateEmail(email) {
    return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);
}

Smooth scrolling:

javascript
document.querySelectorAll('a[href^="#"]').forEach(anchor => {
    anchor.addEventListener('click', function(e) {
        e.preventDefault();
        
        const target = document.querySelector(this.getAttribute('href'));
        if (target) {
            target.scrollIntoView({
                behavior: 'smooth',
                block: 'start'
            });
        }
    });
});

Dynamic content loading:

javascript
function loadContent(url, containerId) {
    fetch(url)
        .then(response => response.text())
        .then(data => {
            document.getElementById(containerId).innerHTML = data;
        })
        .catch(error => {
            console.error('Error loading content:', error);
        });
}

Interactive UI elements:

javascript
// Toggle mobile menu
function toggleMenu() {
    const menu = document.getElementById('mobile-menu');
    menu.classList.toggle('active');
}

// Show/hide modal
function openModal(modalId) {
    document.getElementById(modalId).style.display = 'block';
}

function closeModal(modalId) {
    document.getElementById(modalId).style.display = 'none';
}

// Tabs functionality
function showTab(tabId) {
    // Hide all tab content
    document.querySelectorAll('.tab-content').forEach(tab => {
        tab.style.display = 'none';
    });
    
    // Remove active class from all tab buttons
    document.querySelectorAll('.tab-button').forEach(button => {
        button.classList.remove('active');
    });
    
    // Show selected tab
    document.getElementById(tabId).style.display = 'block';
    event.target.classList.add('active');
}

Working with jQuery

If your web pages include jQuery, you can use jQuery syntax:

javascript
$(document).ready(function() {
    // Form submission
    $('#contact-form').submit(function(e) {
        e.preventDefault();
        
        var email = $('#email').val();
        if (!validateEmail(email)) {
            alert('Invalid email address');
            return false;
        }
        
        // Submit logic
        this.submit();
    });
    
    // Smooth scroll
    $('a[href^="#"]').click(function(e) {
        e.preventDefault();
        var target = $(this.hash);
        $('html, body').animate({
            scrollTop: target.offset().top
        }, 500);
    });
});

Note: Make sure jQuery is loaded before your custom JavaScript:

html
<script src="https://code.jquery.com/jquery-3.6.4.min.js"></script>
<script src="@javascript[your-script,url]"></script>

Using Hubhus placeholders in JavaScript

You can include Hubhus placeholders in your JavaScript for dynamic values:

javascript
// Use account/brand placeholders
const brandName = '%brand_name%';
const brandColor = '%brand_color%';

console.log('Welcome to ' + brandName);

// Apply brand color to elements
document.querySelectorAll('.brand-colored').forEach(element => {
    element.style.color = brandColor;
});

Browser caching explained

How caching works:

  1. Browser requests JavaScript file for the first time
  2. Server sends file with cache headers (600 seconds)
  3. Browser stores file in cache
  4. For next 600 seconds, browser uses cached version
  5. After 600 seconds, browser requests fresh copy

Benefits:

  • Faster page load times
  • Reduced server load
  • Better user experience

During development:

  • Use shorter cache (60-300 seconds)
  • Clear browser cache frequently (Ctrl+Shift+R)
  • Use incognito/private window for testing

In production:

  • Use longer cache (3600+ seconds)
  • Version your scripts if making frequent changes

Organizing JavaScript files

Single file approach:

  • One large JavaScript file with all functionality
  • Simple to manage
  • Larger file size
  • Good for small sites

Multiple file approach:

  • Separate files by purpose:
    • utilities.js - Helper functions
    • validation.js - Form validation
    • analytics.js - Tracking code
    • ui-components.js - Interactive elements
  • More organized
  • Load only needed scripts per page
  • Better for large applications

Naming conventions:

  • Use descriptive names: form-validation, analytics-tracking
  • Include version if needed: app-v2, utils-2024
  • Use consistent slug format: lowercase with hyphens

Best practices

Code organization:

  • Use meaningful variable and function names
  • Add comments for complex logic
  • Group related functions together
  • Use modern JavaScript features (ES6+) when appropriate

Performance:

  • Minimize file size
  • Remove console.log statements in production
  • Avoid memory leaks (clean up event listeners)
  • Use event delegation for dynamic elements

Error handling:

javascript
try {
    // Potentially problematic code
    performAction();
} catch (error) {
    console.error('Error occurred:', error);
    // Graceful fallback
}

Async operations:

javascript
// Use async/await for cleaner code
async function fetchData() {
    try {
        const response = await fetch(url);
        const data = await response.json();
        return data;
    } catch (error) {
        console.error('Fetch error:', error);
    }
}

Browser compatibility:

  • Test in major browsers
  • Use polyfills for older browsers if needed
  • Provide fallbacks for unsupported features
  • Check console for errors in different browsers

Security considerations

Avoid exposing sensitive data:

javascript
// BAD - Don't expose API keys or secrets
const apiKey = 'secret-key-12345'; // Never do this

// GOOD - Use server-side handling for sensitive operations

Validate and sanitize user input:

javascript
function sanitizeInput(input) {
    return input.replace(/[<>]/g, '');
}

const userInput = sanitizeInput(document.getElementById('input').value);

Prevent XSS attacks:

javascript
// BAD - Direct HTML injection
element.innerHTML = userInput;

// GOOD - Use textContent or sanitize
element.textContent = userInput;

Debugging JavaScript

Browser console:

javascript
console.log('Debug message');
console.error('Error message');
console.warn('Warning message');
console.table(arrayData); // Display arrays/objects as table

Breakpoints:

javascript
debugger; // Pauses execution in browser developer tools

Check if elements exist:

javascript
const element = document.getElementById('my-element');
if (element) {
    // Safe to work with element
    element.classList.add('active');
} else {
    console.warn('Element not found');
}

Common integrations

Google Analytics:

javascript
// Track page view
gtag('event', 'page_view', {
    page_title: document.title,
    page_location: window.location.href
});

// Track button click
function trackButtonClick(buttonName) {
    gtag('event', 'button_click', {
        button_name: buttonName
    });
}

Facebook Pixel:

javascript
// Track custom event
fbq('track', 'FormSubmit', {
    form_name: 'contact_form'
});

Custom tracking:

javascript
function trackEvent(category, action, label) {
    // Send to your analytics endpoint
    fetch('/api/track', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json'
        },
        body: JSON.stringify({
            category: category,
            action: action,
            label: label,
            timestamp: new Date().toISOString()
        })
    });
}

Troubleshooting

Script not loading:

  • Verify URL is correct in <script> tag
  • Check browser console for 404 errors
  • Ensure file is saved and published
  • Clear browser cache

Script not executing:

  • Check browser console for JavaScript errors
  • Verify script loads before code that depends on it
  • Ensure DOM elements exist before accessing them
  • Check that element IDs match exactly

Functions not defined:

  • Make sure script loads before calling functions
  • Check function names for typos
  • Verify scope (functions inside DOMContentLoaded not globally accessible)

Changes not appearing:

  • Clear browser cache
  • Wait for cache duration to expire
  • Use incognito/private window
  • Check that you're editing the correct file

Editing existing JavaScript files

To edit a JavaScript file:

  1. Go to Account → Web Resources → JavaScript
  2. Find the file in the list
  3. Click the Edit button (orange pencil icon)
  4. Modify the JavaScript code
  5. Optionally adjust cache duration
  6. Save changes

Important: Users with cached versions will continue using old code until cache expires.


Deleting JavaScript files

To delete a file:

  1. Click the Delete button (red trash icon)
  2. Confirm deletion

Warning:

  • Pages referencing deleted file will have broken functionality
  • Check all pages using the file before deleting
  • Consider renaming to "deprecated-" instead of deleting

Summary

JavaScript files in Hubhus provide centralized, reusable functionality accessible via public URLs with browser caching. Create files in Account → Web Resources → JavaScript with a descriptive name and cache duration. Add JavaScript code without <script> tags, then reference in web pages using <script> tags or placeholders (@javascript[slug,tag], @javascript[slug,url], or @javascript[slug,body]). Place scripts before closing </body> tag for best performance, or in <head> with defer/async attributes. Browser caching (default 600 seconds) improves load times. Use for form validation, interactive UI elements, analytics tracking, and dynamic content. Follow best practices including meaningful naming, error handling, performance optimization, and security considerations. Test across browsers, use console for debugging, and clear cache during development. Combine with Hubhus placeholders for dynamic, personalized functionality.

Was this article helpful?

That’s Great!

Thank you for your feedback

Sorry! We couldn't be helpful

Thank you for your feedback

Let us know how can we improve this article!

Select at least one of the reasons
CAPTCHA verification is required.

Feedback sent

We appreciate your effort and will try to fix the article