Designed and developed by Caleb Theil
The Guerilla Sports CDNFlow system allows developers to build custom functionality into the GS Webflow CMS System, while maintaining a proper Developer Experience, versioning, and management.
This repo provides a solution so managing custom scripts across various pages via the Webflow designer, and instead allows developer to develop tools and deliver them via a 'jsDeliver CDN' directly into the website automatically, without having to touch webflow.
This project provides a structured way to deliver custom JavaScript code to a Webflow site via a CDN. The system is designed to handle global and page-specific functions, with support for multiple DOM events like DOMContentLoaded, load, and others.
The project is organized to separate global functions from page-specific ones, while handling event listener setup in a centralized way for better maintainability and scalability.
src/
├── global/ # Centralized event handler and utility functions
│ ├── functions.ts # global functions to be executed on every page
│ ├── utils.ts # global functions to be executed on every page
│ ├── colors/ # Global function components
├── pages/ # Page-specific directories
│ ├── articles/
│ │ └── init.ts # Functions for /articles page
├── main.ts # Main entry point that sets up the event listeners
├── dist/ # Output for built files (for CDN delivery)
│ ├── bundle.js # What the CDN Delivers
The global/indexs.ts
file sets up listeners for common DOM events like DOMContentLoaded
and load
, and executes the relevant page-specific functions based on the URL.
DOMContentLoaded
: Fired when the DOM is fully loaded, but before external resources like images are done.load
: Fired when the entire page and all its resources have loaded.The global event handler dynamically loads and executes the page-specific functions tied to these events.
Each page has its own init.ts
file inside the pages/<page-name>/
directory. In these files, functions are grouped by the event they should respond to. For example:
DOMContentLoaded
functions: These functions are executed when the DOM is fully loaded.load
functions: These are executed when the entire page has loaded.The main.ts
file handles the detection of the current page based on the URL and delegates the correct page-specific functions to the global event handler. It also ensures that global functions are executed across all pages.
The global/index.ts
file sets up the event listeners:
export const setupGlobalEvents = (pageFunctions: Record<string, any>) => {
// Set up DOMContentLoaded event
window.addEventListener('DOMContentLoaded', () => {
executeFunctionsByEventType({...pageFunctions, ...globalFunctions}, 'DOMContentLoaded');
});
// Set up window load event
window.addEventListener('load', () => {
executeFunctionsByEventType(...pageFunctions, ...globalFunctions, 'load');
});
};
This ensures that each event type is handled in a centralized way, and then delegates the actual execution to the functions defined for each page.
init.ts
FilesEach page defines its functions in a structured way, like so:
src/pages/articles/init.ts
const pageFunctions = {
DOMContentLoaded: {
initHeader: function() {
console.log('Initializing header for articles page');
},
initContent: function() {
console.log('Initializing content for articles page');
}
},
load: {
onPageLoad: function() {
console.log('Page fully loaded for articles page');
}
}
};
export default pageFunctions;
main.ts
)The main.ts
file determines the current page by checking the URL and assigns the correct functions to the event handler:
import { pageFunctions as articlePageFunctions } from './pages/articles/init';
import { pageFunctions as contactPageFunctions } from './pages/contact/init';
import { setupGlobalEvents } from './global';
// Determine current page
const path = window.location.pathname.split('/')[1];
// Load the correct page-specific functions
let currentPageFunctions = {};
if (path === 'articles') {
currentPageFunctions = articlePageFunctions;
} else if (path === 'contact') {
currentPageFunctions = contactPageFunctions;
}
// Pass the functions to the global handler
setupGlobalEvents(currentPageFunctions);
This project is designed to be bundled for CDN delivery. After development, you can build the project and upload the files to your CDN.
To build the project and output the bundled files in the dist/
directory, run:
yarn build
To serve the latest build files from jsDelivr, include the following in your HTML:
<script src="https://cdn.jsdelivr.net/gh/GuerillaSports/CDNFlow@latest/dist/bundle.iife.js"></script>
Custom story titles allow stories
and articles
and other content of the sort which typically rely on story-types
to leverage the rich-thumbnail system and enrich content. Before this feature, the conten's (without a story type) thumnail was empty. This feature (which I believe I just finished for the original developers) allows admins to add a story-title
to the content. The story title is then parsed by this feature and broken up into two parts and injected into the thumbnail.
Each .card-label
already has a .story-titles
div with the story-type
content. This div is only rendered if a story type is set.
.story-titles__custom
data-custom-title={{ Story Title }}
(See How to add custom attributes in webflow)..story-titles__custom
to when a story-type is NOT set && story-title is set
.title-blue
and .title-outline
to the story-title
. Ensure you are only changing the text content for these elements under .story-titles__custom
, not under .story-titles
. guerilla-sports.webflow.io
to ensure the changes worked correctly. You can also check the JS Console where logs should confim custom story title injection like this:
[gs-cdnflow/global]: formatting custom story title