What is the best way to ensure that custom JavaScript and CSS files in Sphinx are always loaded with the most recent changes

Within the configuration file conf.py for Sphinx, I have specified the following:

html_css_files = ['css/custom.css']
html_js_files = ['js/custom.js']

However, any alterations made to custom.js or custom.css do not immediately appear in the user's browser unless the URL http://www.example.com/_static/js/custom.js is forcefully reloaded on the client (same applies for CSS).

Is there a way to ensure that the custom CSS + JS files are never cached by the user's browser?

Answer №1

Update for Latest Versions of Sphinx

Recent builds using the following solution are encountering failures with the error message:

Reason: ThemeError("Local asset file paths must not contain query strings: '_static/custom.css?v=12345678'")

Bug reports indicate that this issue has also affected builds in other major projects such as MathJax, NumPy, Gentoo, and Bokeh.

As per a comment by a contributor to Sphinx, the new approach involves Sphinx handling cache busting through a content checksum, eliminating the need for manual cache busting.

Version Compatibility for Older Sphinx Releases

Although the configuration file seems to only support standard string values, it is essentially a Python script allowing us to utilize functions like a random number generator.

Add the following line at the top of conf.py:

from secrets import token_urlsafe

Modify your custom CSS + JS as follows:

html_css_files = [f'css/custom.css?v={token_urlsafe(8)[:8]}']
html_js_files = [f'js/custom.js?v={token_urlsafe(8)[:8]}']

This change will ensure that your custom CSS + JS files load similar to vanilla CSS + JS files, with an 8-character random slug appended at the end, thus preventing caching:

<!-- Vanilla CSS from Sphinx: -->
<link rel="stylesheet" type="text/css" href="../_static/pygments.css?v=80d5e7a1" />
<link rel="stylesheet" type="text/css" href="../_static/css/theme.css?v=19f00094" />
<link rel="stylesheet" type="text/css" href="../_static/copybutton.css?v=76b2166b" />

<!-- Custom CSS now includes a random slug, similar to vanilla: -->
<link rel="stylesheet" type="text/css" href="../_static/css/custom.css?v=Rdy7RNCQ" />

<!-- Vanilla JS from Sphinx: -->
<script src="../_static/jquery.js?v=5d32c60e"></script>
<script src="../_static/_sphinx_javascript_frameworks_compat.js?v=2cd50e6c"></script>
<script data-url_root="../" id="documentation_options" src="../_static/documentation_options.js?v=e91dff3d"></script>
<script src="../_static/doctools.js?v=888ff710"></script>
<script src="../_static/sphinx_highlight.js?v=4825356b"></script>
<script src="../_static/clipboard.min.js?v=a7894cd8"></script>
<script src="../_static/copybutton.js?v=f281be69"></script>

<!-- Custom JS now includes a random slug, similar to vanilla: -->
<script src="../_static/js/custom.js?v=8QronLhw"></script>

It's important to note that if you're using Sphinx within a Docker environment, the ?v=xxxxxxxx slug may remain unchanged unless you utilize the --no-cache option when running your docker build.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

How to resize and center an image within a div element as they both scale proportionally

Can someone help me figure out how to center a resized image within its container, which should also be centered? I've been struggling with this for 7 hours and can't seem to get it right. Any assistance would be greatly appreciated :-) Here is ...

NodeJS: Increasing memory consumption leads to system failure due to recursive scraping

Currently, I am utilizing a GET URL API in NodeJS to extract various data by looping through the months of the year across multiple cities. For each set of parameters such as startDate, endDate, and location, I invoke a scrapeChunk() function. This functio ...

Display 1 row of content on larger LG screens and 2 rows on medium-sized MD screens using Bootstrap

How can I achieve 1 row with 12 cells on a large screen in Bootstrap, and for a smaller screen have 2 rows with 6 cells? Here is a visual representation of what I am trying to accomplish: https://i.stack.imgur.com/NgfaP.png This is the code I attempted: ...

Issue encountered while compiling ReactJs: Unexpected token error found in App.js

I executed the commands below. npx create-react-app github-first-app npm install --save react-tabs npm i styled-components npm install git-state --save using the following code files App.js import React from "react"; import Layout from " ...

I'm having trouble with my dropdown navigation menus - they keep popping back up and I can't seem to access

My website is currently in development and can be accessed at: The top navigation bar on the homepage functions properly across all browsers. However, there are three sections with dropdown submenus - About Us, Training, and Careers. These dropdown submen ...

A step-by-step guide to customizing the Material UI Chips delete SVG icon to appear in white color through

Using a Material UI component, I added a custom class to my chip. Attached is a screenshot showing what I mean. Currently, I am attempting to change the color of the cross button to white. After inspecting the element, I discovered that it is an SVG ico ...

Seeking assistance in identifying the highest value in JavaScript (excluding the use of the max method)

Greetings and thank you for stopping by. I'm new to Javascript and currently facing an issue that I could use some help with. I am trying to identify the highest number from a set of variables using conditional statements within a function, but I seem ...

What takes precedence in npm scripts - local dependencies or global ones?

When using npm scripts, the ./node_modules/.bin path is automatically added to your PATH. This means that by simply running npm test with the provided package.json, npm will utilize the local version of mocha located in ./node_modules/.bin. "scripts": { ...

Removing Redux State in ReactDeleting data from Redux in a

After displaying a list of data on a table, I have implemented a View component where specific data from the list is passed. However, I am facing an issue when attempting to delete something in the View modal dialog as the redux data delete reducer does no ...

Experiencing difficulties when establishing a connection between MongoDB and Node.js

I'm encountering an issue when attempting to connect MongoDB and Node.js on my local server. Can anyone assist me with solving this problem? Below is my JavaScript code: const mongodb = require("mongodb"); // Provide the function to connect to the d ...

Deleting elements from the DOM in Vue.js

Utilizing Vue.js (version 3.x), I am dynamically rendering components. <div v-for="(i, index) in fields" > <my-component :id="index" ></my-component> <span class="delete-icon" @click="removeFi ...

Steps to hide a div after it has been displayed once during a user's session

After a successful login, I have a div that displays a success message and then hides after 4 seconds using the following JavaScript code: document.getElementById('success').style.display = 'none'; }, 4000); While this functionality wo ...

Load Angular template dynamically within the Component decorator

I am interested in dynamically loading an angular template, and this is what I have so far: import { getHTMLTemplate } from './util'; const dynamicTemplate = getHTMLTemplate(); @Component({ selector: 'app-button', // templat ...

No data is being retrieved by SWR

I'm struggling to make SWR work in my code. Despite trying multiple examples, I can't seem to get it functioning properly. It's frustrating because the code looks fine and should work. I feel like I must be missing something simple. Current ...

How can you eliminate a specific element from an HTML document?

Utilizing localStorage can be tricky when it comes to keeping the JSON file hidden from being displayed on the HTML page. One approach I used involves sending the JSON file to the client once and then performing all logic using that file. To prevent the JS ...

How can I determine if my clients are utilizing the CDN or NPM versions of my JavaScript library?

At this moment, I'm contemplating releasing an open-source version of my library on NPM. My main concern is figuring out how to track the usage of my CDN or NPM by clients. Is there a method available to achieve this? ...

Is it possible to add a border to both the tbody and td

I currently have a table that is organized with tbody elements to group rows together. In order to create a grid-like structure, I applied borders to each individual td element within the tbody. However, I also desire to show that the tbodies themselves ar ...

Is there a way to adjust the transparency of a span element's background without affecting the text itself?

I have some code that needs to be customized. This is my HTML: <div class="text-rotator add-top-half add-bottom-half align-left white-txt medium-txt uppercase highlight-bg"> <div class="rotator-wrap" style="display: block;"> <sp ...

Can someone please explain how to apply various fonts to the text in a `<p>` paragraph using CSS and HTML?

Take a look at this image Can you provide guidance on how to incorporate various fonts within a paragraph, like the example shown in the image above? I am experimenting with the "Creative Corner" section. ...

Break down a data structure into a type that includes multiple options

Is it possible for Typescript to support type or interface "destructuring" (if that's the right term)? I am attempting to achieve something similar to the code snippet below: type SomeRandomType = { propertyOne: string; propertyTwo: number; ...