Migrating My Interactive Morse Code Translator Website to Jekyll

I run a fairly advanced Morse Code translator website that allows users to convert text into Morse code and decode Morse messages back into readable text in real time. The website includes JavaScript-powered translation logic, Morse code audio playback, copy-to-clipboard functionality, downloadable outputs, and educational content for beginners learning Morse code. I am currently considering migrating the content portion of the site to Jekyll in order to benefit from a simpler deployment workflow, improved maintainability, and static-site performance. However, I am encountering several architectural questions regarding how best to integrate a highly interactive web application into a framework that is primarily designed for static content generation.

One of the biggest challenges involves organizing the translator’s JavaScript and frontend assets within a Jekyll project. The Morse Code application currently consists of multiple JavaScript modules responsible for encoding, decoding, audio generation, keyboard interactions, and UI updates. In a traditional web application structure this is straightforward, but within a Jekyll-based site I am unsure whether these files should simply be served as static assets, processed through external build tools, or integrated into the Jekyll workflow itself. I would appreciate advice from developers who have managed larger frontend applications inside Jekyll projects without creating a maintenance burden.

Another concern relates to reusable components and content integration. I plan to publish tutorials, Morse code learning guides, and technical articles throughout the website, and ideally I would like to embed translator widgets directly within selected pages. My initial thought was to use includes or custom layouts, but the translator requires dynamic initialization, event listeners, and audio-related setup that may be instantiated multiple times on the same page. I am unsure whether Jekyll’s include system is the best approach for embedding interactive widgets or whether a separate client-side application architecture would be more appropriate.

Performance and user experience are also important considerations. One of the reasons I am interested in Jekyll is its excellent static-site performance, but my Morse Code translator relies heavily on real-time browser interactions and precise timing for Morse audio playback. As I continue adding educational content, search functionality, analytics scripts, and potentially third-party integrations, I am concerned about maintaining responsiveness on mobile devices. I would like recommendations on asset optimization, script loading strategies, and frontend architecture patterns that align well with Jekyll while preserving a highly interactive user experience.

Another challenge is deployment and cache management. The translator’s functionality evolves frequently, with regular updates to translation logic, audio controls, and interface behavior. Because of this, I need a reliable way to ensure visitors receive the latest JavaScript and CSS assets after each deployment without causing unnecessary cache invalidation across the entire site. I understand Jekyll itself is focused on content generation rather than asset versioning, so I am interested in learning what solutions the community typically uses for fingerprinting, cache busting, and deployment automation in projects that contain substantial client-side functionality.

Finally, I would greatly appreciate guidance from experienced Jekyll users regarding whether Jekyll is the right long-term platform for a website that combines educational content with a sophisticated interactive Morse Code application. Would you recommend fully integrating the translator into the Jekyll site using includes, layouts, and static assets, or would it be better to maintain the translator as a separate frontend application and embed it where needed? Any advice on project structure, performance optimization, deployment workflows, and maintainability would be extremely valuable as I plan the next stage of development. Sorry for long post!

Dear Ben: Yours sounds like impressive work. I have a somewhat similar situation: Here https://michaelbach.de/ot/ are 100 interactive javascript programs, they are simply served statically. Here https://michaelbach.de/fract/ is a more sizable javascript project, where I solve the stale-cache problem with a PWA approach: The webworker, which via `cache.addAll` ensures all parts are loaded, includes a cache name. The latter is updated whenever the web app changes. This ensures up-to-date files, at least if you reload after ½minute.

All production work is done locally and then simply synched to online via the enormously versatile `lftp`, all shell scripted.

Unsolved for me is visual-auditory synchronization. What was easy with Flash decades ago I now have to solve with a user-operated initial calibration, every browser has different timing. So this here remains somewhat ugly https://michaelbach.de/ot/aud-bounce/. Do you have a solution to visual-auditory synchronization?

Thanks for the detailed reply and for sharing your projects they’re great examples of how far you can push client-side JavaScript while still serving everything statically.

Your approach of treating the interactive applications as static assets alongside the content is encouraging, because that’s very close to the architecture I’ve been considering for the Morse Code translator. The PWA-based cache versioning strategy is particularly interesting. I’ve been thinking about asset fingerprinting or build-time hashing, but using a cache name version inside the service worker sounds like a practical solution for ensuring users receive updated translation logic and UI assets without having to invalidate everything manually.

Regarding visual-auditory synchronization, I’ve run into similar challenges. In my case, I generate Morse tones using the Web Audio API rather than relying on timers alone, because audio scheduling through AudioContext.currentTime tends to be much more precise. For synchronization, I try to schedule both the audio events and the visual updates from a common timing reference whenever possible. Even then, browser differences, device performance, and audio output latency can still introduce drift. I haven’t found a completely universal solution yet, but moving timing-critical operations into the audio scheduler has been noticeably more reliable than using setTimeout() or animation timing alone.

Your experience also reinforces my feeling that Jekyll can probably handle the content side of the site very well, while the translator remains a self-contained client-side application served alongside it. That seems like a cleaner long-term path than trying to tightly couple every piece of application logic into the static-site generation workflow. Thanks again for sharing your approach and the synchronization example it’s helpful to hear from someone dealing with similar browser-timing challenges.