RJLCustom404 Logo

RJLCustom404 - Custom 404 Page Generator

This script dynamically generates a customizable 404 error page with advanced features.

Brought to you by RJL.io, available from RJL.codes

GitHub Repository

Overview Overview

RJLCustom404 is a free, open-source JavaScript 404 error page generator that turns the default "page not found" dead end into a polished, on-brand experience. Drop a single <script> tag into your site and get a fully customizable 404 page with zero dependencies, zero frameworks, and zero CSS required.

Unlike generic error pages that drive visitors away, RJLCustom404 keeps users engaged with dynamic, randomized images that cycle on every visit, configurable headings and sub-text, styled action buttons that guide users back to your content, and responsive layouts that look great on desktop and mobile alike.

Configuration options for colors, images, buttons, text, and layout
Dependencies — pure vanilla JavaScript, works in every modern browser
Line to integrate — add one script tag and call RJLCustom404()

Whether you need a simple custom 404 page for a personal blog, a branded error page for a SaaS product, or a dynamic 404 page with rotating imagery for a portfolio site, RJLCustom404 gives you full control without writing a single line of CSS. Configure everything through a clean JavaScript API, preview your changes in real-time with the live configurator below, and deploy in minutes.

Usage Installation & Usage

Download the JavaScript File from GitHub. Add this code to your HTML file before the </head> tag:

Customizations Make Your Customizations

Opens a preview of your customized 404 page in a new tab Resets all customizations to default values

Options Configuration Options

All color options accept any valid CSS color: rgb(), hex, hsl(), or named colors. Click any option below to see full details, code examples, and interaction notes.

Page & Body

pageTitle
Type: string
Default: "404 - Not Found"

Sets the document.title displayed in the browser tab. This is the first thing users see when they land on your 404 page.

RJLCustom404({ pageTitle: "Oops! Page Not Found" });

Validation: Accepts any string. Falls back to default if not provided.

bodyBackgroundColor
Type: string (CSS color)
Default: "white"

Sets the background-color on the page body. When using a dark background, set bodyFontColor to a light color for readability.

RJLCustom404({ bodyBackgroundColor: "#1a1a2e" });

Validation: Applied as CSS. Invalid colors are ignored by the browser.

bodyFontColor
Type: string (CSS color)
Default: "black"

Sets the text color on the page body. When set to "black" (default), the subHeaderText automatically renders in #666 for visual hierarchy.

RJLCustom404({ bodyFontColor: "#e0e0e0", bodyBackgroundColor: "#1a1a2e" });

Interaction: When "black", sub-header auto-lightens to #666. Other colors are inherited as-is.

autoText
Type: boolean
Default: false

When true, automatically fills pageTitle, headerText, subHeaderText, and btnDisplayText with randomly selected phrases from built-in arrays of 50 entries each. A mix of funny, humorous, and professional text is included. User-provided values for individual fields always take priority.

RJLCustom404({ autoText: true });

Interaction: Only fills fields not explicitly set by the user. Setting subHeaderText: "" with autoText: true suppresses the sub-header (empty string counts as explicitly set).

Images

imgFileNames
Type: array
Default: ["/errors/404-1.webp", ...]

Array of image URLs for the 404 page. One is randomly selected per load, cycling through all before repeating. Each string should be a path relative to your domain root or a full URL.

RJLCustom404({ imgFileNames: ["/img/404-a.webp", "/img/404-b.webp"] });

Validation: Must be a non-empty array. Empty array warns and falls back to defaults.

imgPattern
Type: string
Default: "" (disabled)

A path template with a {n} placeholder that gets replaced with the image number. Use {nn} for 2-digit zero-padding (01, 02...) or {nnn} for 3-digit (001, 002...). Requires imgCount to be set.

RJLCustom404({ imgPattern: "/errors/404-{n}.webp", imgCount: 20 });

Dependency: Requires imgCount. Ignored if imgFileNames array is provided.

imgCount
Type: number
Default: 0 (disabled)

The total number of images to generate from the imgPattern template. For example, imgCount: 20 generates 20 image paths.

RJLCustom404({ imgPattern: "/errors/404-{n}.webp", imgCount: 20 });

Dependency: Requires imgPattern. Must be greater than 0. Ignored if imgFileNames array is provided.

imgStartIndex
Type: number
Default: 1

The starting number for image generation. Default is 1 (1-based numbering). Set to 0 for 0-based numbering.

RJLCustom404({ imgPattern: "/errors/404-{nn}.webp", imgCount: 10, imgStartIndex: 0 });

Dependency: Only used with imgPattern and imgCount. Must be non-negative.

imgBorderRadius
Type: string (CSS length)
Default: "50%"

Controls the border-radius on the 404 image. Default "50%" makes images circular. Use "0" for square corners.

RJLCustom404({ imgBorderRadius: "10px" });

Valid values: Any CSS border-radius value: "0", "10px", "50%", "1em".

imgBoxShadow
Type: boolean
Default: false

When true, a box-shadow appears on image hover. Shadow size and color are set by imgBoxShadowSize and imgBoxShadowColor.

RJLCustom404({ imgBoxShadow: true, imgBoxShadowSize: "10px", imgBoxShadowColor: "rgba(0,0,0,0.3)" });

Interaction: When false, imgBoxShadowSize and imgBoxShadowColor have no effect.

imgBoxShadowSize
Type: string (CSS length)
Default: "5px"

Sets the blur radius of the image hover shadow. Larger values produce a softer, more spread-out shadow.

RJLCustom404({ imgBoxShadow: true, imgBoxShadowSize: "15px" });

Dependency: Requires imgBoxShadow: true.

imgBoxShadowColor
Type: string (CSS color)
Default: "rgba(18, 0, 100, .4)"

Sets the color of the image hover shadow. The default is a semi-transparent dark blue. Use rgba() for transparency control.

RJLCustom404({ imgBoxShadow: true, imgBoxShadowColor: "rgba(0,0,0,0.5)" });

Dependency: Requires imgBoxShadow: true.

maxImgWidth
Type: string (CSS length)
Default: "1000px"

Sets the max-width on the image container. The image scales responsively within this maximum.

RJLCustom404({ maxImgWidth: "600px" });

Valid values: Any CSS length: "500px", "80%", "50vw".

imgResponsiveBreakpoints
Type: boolean
Default: true

When true, responsive CSS breakpoints adjust image margins, button padding, and font sizes at 768px and 480px widths for mobile devices.

RJLCustom404({ imgResponsiveBreakpoints: false });

Interaction: When false, the layout does not adapt to smaller screens.

Button

actionIsBtn
Type: boolean
Default: true

When true, the return action renders as a styled button. When false, it renders as a plain underlined text link.

RJLCustom404({ actionIsBtn: false });

Interaction: When false, btnColor, btnPulsate, and btnPulsateCount have no visible effect.

btnColor
Type: string (CSS color)
Default: "blue"

Sets the background color of the action button. Button text is always white.

RJLCustom404({ btnColor: "#e74c3c" });

Dependency: Only visible when actionIsBtn: true.

btnPulsate
Type: boolean
Default: true

When true, the button plays a scale pulsing animation to attract user attention.

RJLCustom404({ btnPulsate: false });

Dependency: Requires actionIsBtn: true. When false, btnPulsateCount has no effect.

btnPulsateCount
Type: number
Default: 2

How many times the button pulse animation plays (~2 seconds per cycle). Set to 0 to disable animation even when btnPulsate is true.

RJLCustom404({ btnPulsateCount: 5 });

Dependency: Requires actionIsBtn: true and btnPulsate: true. Negative values warn and fall back to 2.

btnDisplayText
Type: string
Default: "Back to"

The text on the return button or link. When btnDisplayHostName is true, the hostname is appended (e.g., "Back to example.com").

RJLCustom404({ btnDisplayText: "Return to " });

Interaction: Combined with btnDisplayHostName to form the full text.

btnDisplayHostName
Type: boolean
Default: true

When true, window.location.hostname is appended to the button text. E.g., "Back to example.com".

RJLCustom404({ btnDisplayHostName: false, btnDisplayText: "Go Home" });

Header & Text

headerText
Type: string
Default: "404 - File not found"

The primary heading displayed on the 404 page, rendered as an <h3> element.

RJLCustom404({ headerText: "Whoops! This page doesn't exist." });
subHeaderText
Type: string
Default: "" (not shown)

A paragraph below the header text. Empty by default (nothing renders).

RJLCustom404({ subHeaderText: "The page you're looking for has moved." });

Interaction: When bodyFontColor is "black", this auto-lightens to #666.

headerTextColor
Type: string (CSS color)
Default: "" (inherits bodyFontColor)

Sets a custom color for the <h3> header text. When empty, the header inherits its color from bodyFontColor.

RJLCustom404({ headerTextColor: "#e74c3c" });
subHeaderTextColor
Type: string (CSS color)
Default: "" (auto from bodyFontColor)

Sets a custom color for the sub-header paragraph. When empty, the color is automatically derived from bodyFontColor (lightened to #666 when black).

RJLCustom404({ subHeaderText: "We couldn't find that page.", subHeaderTextColor: "#3498db" });

Override: When set, this overrides the auto-lighten behavior from bodyFontColor.

headerTextPosition
Type: string
Default: "top"
Valid: "top" | "left" | "right"

"top" stacks text above the image. "left"/"right" places text beside the image in a side-by-side layout. Invalid values warn and fall back to "top".

RJLCustom404({ headerTextPosition: "left" });

Responsive: On screens < 768px, "left" and "right" collapse to stacked layout for mobile readability.

Frequently Asked Questions

What is RJLCustom404?

RJLCustom404 is a lightweight and dynamic 404 error page generator that allows users to customize error page content, styles, and images effortlessly. It supports randomized images, dynamic text, button options, and easy integration into any website.

How do I install RJLCustom404?

Download the JavaScript file from GitHub and add it to your HTML file before the closing </head> tag. Then initialize it with your custom options using the RJLCustom404() function.

Is RJLCustom404 free to use?

Yes, RJLCustom404 is completely free to use. You can download it from GitHub and integrate it into your website without any cost.

Can I customize the appearance of the 404 page?

Absolutely! RJLCustom404 offers 25 customization options including background colors, font colors, custom images, pattern-based image configuration, button styles, border radius, shadows, auto-generated text, and more. You can preview your customizations live on this page before implementing them.

What browsers does RJLCustom404 support?

RJLCustom404 is built with vanilla JavaScript and works on all modern browsers including Chrome, Firefox, Safari, Edge, and Opera. It requires no dependencies or frameworks.

How do I preview my customizations?

Use the live configurator on this page. Edit the JSON options in the text area under "Make Your Customizations" and click "Preview Your 404 Page" to see a live preview. Your settings are saved in your browser for 10 minutes so you can experiment freely.

Can I use my own custom images?

Yes! Use the imgFileNames option to provide an array of your own image paths, or use imgPattern with imgCount to generate paths from a naming pattern. The script randomly cycles through all images before repeating, giving visitors a unique experience on each visit.

How do I configure images using a pattern?

Instead of listing every image path individually, use imgPattern with a {n} placeholder and imgCount to auto-generate paths. For example, imgPattern: "/errors/404-{n}.webp" with imgCount: 20 generates paths from 404-1.webp through 404-20.webp. Use {nn} for zero-padded numbers (01, 02) or {nnn} for 3-digit padding (001, 002). Set imgStartIndex: 0 for 0-based numbering.

Does RJLCustom404 work on mobile devices?

Yes. With imgResponsiveBreakpoints enabled (the default), the layout automatically adapts for mobile screens at 768px and 480px breakpoints, adjusting image sizes, button padding, and font sizes for an optimal experience on any device.