Initial commit: Docusaurus docker stack and docs

This commit is contained in:
Johan
2026-07-15 18:57:47 +00:00
commit d5b8c97ec3
61 changed files with 1857 additions and 0 deletions

12
.env Normal file
View File

@@ -0,0 +1,12 @@
# Container name — this is the DNS name Nginx Proxy Manager forwards to on
# the "proxy" network (Forward Hostname/IP: docusaurus-docs, Port: 3000).
CONTAINER_NAME=docusaurus-docs
# Port Docusaurus serves on inside the container.
PORT=3000
# Production URL of the docs site. Update this once you've picked the
# subdomain, then run `docker compose up -d --build` to rebuild with it —
# Docusaurus bakes the URL into the built site (canonical links, sitemap,
# social card meta tags), it isn't read at request time.
SITE_URL=https://docs.dotjuice.co.uk

73
README.md Normal file
View File

@@ -0,0 +1,73 @@
# Dotjuice Docs (Docusaurus)
Self-hosted documentation site, built with [Docusaurus](https://docusaurus.io) v3.10.2.
## Layout
```
docker-compose.yaml # the stack
.env # container name, port, production URL
site/ # the Docusaurus app itself (config, theme, homepage) — built into the image
docs/ # the actual markdown content — bind-mounted, edit freely without rebuilding
```
`docs/` is organised one folder per plugin, matching the sidebar:
```
docs/
intro.md # docs landing page (served at /docs/)
dotjuice-elementor-tools/ # free plugin
getting-started.md
screenshot-api-settings.md
woocommerce-account-settings.md
product-attribute-colours.md
widgets/ # one file per widget
dotjuice-elementor-tools-pro/ # pro plugin
getting-started.md
license-activation.md
widgets/
dotjuice-pagespeed/ # pagespeed plugin (flat, no widgets/ subfolder)
getting-started.md
caching.md, css-optimisation.md, ...
```
Each plugin folder has a `_category_.json` controlling its sidebar label and position — the sidebar itself is fully auto-generated from this folder structure (`sidebars.js`), so adding a new `.md` file anywhere under `docs/` makes it appear automatically, no config edit needed.
## Spinning it up
```bash
cd /home/jandieman/docker/docusaurus
docker compose up -d --build
```
First build takes a minute or two (`npm install` inside the image). After that, `docker compose logs -f docusaurus` should show `[SUCCESS] Serving "build" directory at: http://0.0.0.0:3000/`.
Point Nginx Proxy Manager's proxy host at:
- **Forward Hostname/IP:** `docusaurus-docs` (the container name — resolvable by any container on the shared `proxy` network)
- **Forward Port:** `3000`
## Editing content
Edit or add markdown files under `docs/`, then either:
```bash
docker compose restart docusaurus # picks up doc changes, same image
```
or, if you've changed `site/` (theme, config, navbar, homepage):
```bash
docker compose up -d --build # rebuilds the image too
```
Either way, the container rebuilds the static site fresh on every start — there's no separate "build step" to remember, just restart the container after editing.
## Changing the production URL
Edit `SITE_URL` in `.env`, then `docker compose up -d --build`. Docusaurus bakes this URL into the built site (canonical links, sitemap, social-card meta tags), so it needs a rebuild to take effect — it isn't read live per-request.
## Known follow-up
A handful of "See Pro" / "See free plugin" cross-links inside the docs were written for the original plugin repo structure and were adjusted during setup — all internal links were checked and resolve correctly as of this build. If you reorganise the `docs/` folder structure later, re-check cross-plugin links (the free and pro plugin folders link to each other in a few places, e.g. product-attribute-colours ↔ the Pro widget that displays swatches).
The marketing/"what it does" copy (as opposed to this how-to content) is intended for regular Elementor pages on dotjuice.co.uk, not this docs site — see each plugin's `documentation/marketing/` folder in its own repo.

30
docker-compose.yaml Normal file
View File

@@ -0,0 +1,30 @@
networks:
proxy:
external: true
services:
docusaurus:
container_name: ${CONTAINER_NAME}
build:
context: ./site
restart: always
environment:
SITE_URL: ${SITE_URL}
NODE_ENV: production
volumes:
# The markdown source content — edit files here, then
# `docker compose up -d --build` (or just `restart`) to rebuild and
# pick up the changes. Organised as one folder per plugin.
- ./docs:/app/docs
# Rebuilds the static site fresh on every container start (picking up
# whatever is currently in ./docs and the current SITE_URL), then serves
# the result. A few seconds slower to start than pre-built static files,
# but means editing docs never requires touching the image.
command: sh -c "npm run build && npm run serve -- --host 0.0.0.0 --port ${PORT}"
networks:
- proxy
# No host port published — Nginx Proxy Manager reaches this container
# directly by its container name on the shared "proxy" network. Point
# NPM's proxy host at http://${CONTAINER_NAME}:${PORT}.
# ports:
# - "3000:3000"

View File

@@ -0,0 +1,5 @@
{
"label": "Elementor Tools Pro",
"position": 3,
"link": { "type": "doc", "id": "dotjuice-elementor-tools-pro/getting-started" }
}

View File

@@ -0,0 +1,54 @@
# EspoCRM Lead Capture
**Requires Elementor Pro** — this adds a submit action to Elementor Pro's Forms widget, so it only appears if Elementor Pro's Forms module is active.
## Where to find it
Edit any Elementor Form widget, go to **Content → Actions After Submit**, and add **EspoCRM Webhook** to the list of actions. A new "EspoCRM Webhook" settings section appears further down the panel once it's added.
## Setting it up
1. In EspoCRM, create (or open) a **Lead Capture** entry point and copy its webhook URL.
2. Paste that URL into **Webhook URL** on the form action.
3. Tell it which fields to send — see **Field mapping** below.
4. Save and test with a real submission, checking that the lead appears correctly in EspoCRM.
## Settings
| Setting | Default | What it does |
|---|---|---|
| **Webhook URL** | Empty | Your EspoCRM Lead Capture endpoint. Required — the form shows an error to the visitor if this is empty when they submit. |
| **EspoCRM Payload Example** | Empty | Paste an example payload copied from EspoCRM's Lead Capture setup here — see below. |
| **Or Enter Field IDs Manually** | Empty | A comma-separated list of field IDs to send, as an alternative to pasting a payload. |
| **Format Phone Numbers** | On | Automatically reformats UK phone numbers to `+44 #### ######` before sending. |
| **Enable Debug Logging** | Off | Logs each submission's request and response to your site's debug log — see the warning below before using this on a live site. |
## Field mapping
This integration works by matching each Elementor form field's **ID** directly against the field name EspoCRM expects — there's no visual field-mapping screen, so the IDs need to line up.
**The easiest way:** copy an example payload from your EspoCRM Lead Capture setup (it looks like `{"firstName": "...", "lastName": "...", "emailAddress": "..."}`) and paste it into **EspoCRM Payload Example**. The field names are extracted automatically — you don't need to type them out separately.
**Alternative:** if you don't have an example payload handy, list the field IDs you want sent, comma-separated, in **Or Enter Field IDs Manually** (e.g. `firstName, lastName, emailAddress`).
**If both are left empty**, every field on the form is sent (except Elementor's own internal fields — acceptance checkboxes, terms, reCAPTCHA, honeypot, which are always excluded automatically).
Either way, each Elementor form field's **ID** must match the corresponding EspoCRM field name exactly. To check or change a field's ID: select the field in the form editor → **Advanced** tab → **ID**.
## Phone number formatting
When **Format Phone Numbers** is on, any field whose ID contains "phone" is reformatted to `+44 #### ######` before sending — handling common UK input styles (a leading `0`, `+44`, or `0044`) automatically. If a number doesn't look like a valid 10-digit UK number after cleanup, it's sent as originally entered rather than a mangled result. This formatting is UK-specific; international numbers are passed through unchanged.
## ⚠ Before enabling debug logging
Debug logging writes each submission's field values — potentially including names, emails, and phone numbers — to your site's debug log file. Only enable this temporarily while troubleshooting a specific issue, and turn it off again afterward. Debug logs aren't intended to store personal data long-term, and depending on your hosting, the log file may be more widely accessible than your database.
## What visitors see if something goes wrong
If the webhook URL is missing, unreachable, or EspoCRM returns an error, the visitor sees a generic error message on the form rather than technical details — enable debug logging temporarily to see exactly what EspoCRM returned.
## Good to know
- **Checkbox/toggle-style fields** are converted to `0`/`1` automatically, matching EspoCRM's expected boolean format.
- **Multi-select or checkbox-group fields** are sent as a single comma-separated string.
- **Empty fields are omitted** from the payload entirely rather than sent as blank values.

View File

@@ -0,0 +1,46 @@
# Getting Started
## Requirements
Dotjuice Elementor Tools Pro requires:
- **The free [Dotjuice Elementor Tools](../../../dotjuice-elementor-tools/documentation/marketing/overview.md) plugin**, installed and active — Pro is an add-on, not a standalone plugin.
- **Elementor** (required by the free plugin).
- **WooCommerce**, for every WooCommerce-related widget (all of them except ACF Frontend Form).
- **Advanced Custom Fields (ACF)**, only for the ACF Frontend Form widget.
- **Elementor Pro**, only for Woo Quick View's popup and the [EspoCRM Lead Capture](espocrm-integration.md) integration (Forms is an Elementor Pro feature).
## Activating your license
Before any Pro feature works, you need to activate your license key. Go to **Dotjuice → Pro Licence** in your WordPress admin and enter the key from your purchase email. See [Activating Your License](license-activation.md) for the full walkthrough, including what each status message means and what to do if activation fails.
**Until your license is active, Pro widgets won't appear in the Elementor panel and watermarks stay on Screenshot Capture** — this is expected, and resolves as soon as your key is activated.
## Finding your widgets
Once your license is active, open the Elementor editor and look in the **Dotjuice** category — your Pro widgets appear alongside the free plugin's widgets there, each carrying a small Pro badge in the panel.
If a specific widget is missing:
- **All WooCommerce widgets** need WooCommerce active.
- **ACF Frontend Form** needs Advanced Custom Fields active.
- **Woo Quick View** needs **Elementor Pro** for its popup functionality — without Elementor Pro, its button falls back to a plain link to the product page instead of opening a popup.
## Widget guides
- [Woo Product Filter](widgets/woo-product-filter.md)
- [Woo Cart](widgets/woo-cart.md)
- [Woo Quick View](widgets/woo-quick-view.md)
- [Woo Custom Product Tabs](widgets/woo-custom-product-tabs.md)
- [Woo Add Product Tab](widgets/woo-add-product-tab.md)
- [ACF Frontend Form](widgets/acf-frontend-form.md)
## Integrations
- [EspoCRM Lead Capture](espocrm-integration.md) — send Elementor Pro Form submissions straight into EspoCRM.
## Recommended first steps
1. Activate your license (above).
2. If you're setting up product filtering, read [Woo Product Filter](widgets/woo-product-filter.md) in full before building your first filter group — it has several settings that interact with each other.
3. If you're setting up Quick View, read [Woo Quick View](widgets/woo-quick-view.md) — it's a two-widget system and needs a specific setup order.

View File

@@ -0,0 +1,43 @@
# Activating Your License
**Dotjuice → Pro Licence**
## Activating for the first time
1. Find your license key in your purchase confirmation email — it looks like `DJ-XXXX-XXXX-XXXX-XXXX`.
2. Go to **Dotjuice → Pro Licence** in your WordPress admin.
3. Paste your key into the License Key field and click **Activate Licence**.
4. Once active, the field becomes read-only and the page shows your license status, how many sites you're using out of your plan's limit, and confirms Pro features are unlocked.
## What each status means
| Status shown | What it means |
|---|---|
| **Active — lifetime licence** | Fully valid, never expires. |
| **Active — renews [date]** | Fully valid, on a subscription that renews on the date shown. |
| **Active** | Fully valid. |
| **Expired — Pro features are disabled until you renew** | Your license has lapsed. A "Renew your licence" button takes you to your account on the Dotjuice shop. |
| **Revoked — please contact support** | Your license has been cancelled or pulled. Contact support to resolve this. |
| **Key valid but not activated for this site** | Your key is real, but hasn't been activated for this specific site yet — click Activate. |
| **Site limit reached — deactivate another site or upgrade** | You've used up every site activation your plan allows. Deactivate the license on a site you no longer need it on (from your account on the Dotjuice shop, or from that site's own Pro Licence page), or upgrade to a plan with a higher site limit. |
| **Invalid licence key** | The key doesn't match any license on file — check for typos, or that you're using the key for this specific product. |
| **Not activated** | No key has been entered yet. |
## Other actions on this page
- **Re-check Status** — forces an immediate recheck against the license server, useful right after renewing or resolving a site-limit issue elsewhere.
- **Deactivate** — removes the license from this specific site, freeing up that site slot for use elsewhere (for example, if you're moving the plugin from a staging site to production). Pro features switch off on this site immediately.
## What happens while your license isn't active
Pro widgets don't appear in the Elementor editor's widget panel, and any Pro widgets already placed on a page before your license lapsed won't render on the live site. The free plugin's Screenshot Capture widget keeps its watermark. Everything reactivates automatically the moment your license is valid again — nothing needs to be rebuilt or re-placed.
## If activation keeps failing
- Double-check the key was copied correctly, with no extra spaces (copying directly from your purchase email is safest).
- Confirm you're activating the correct product — a key issued for a different Dotjuice product won't activate here.
- If you're confident the key is correct and still see "Invalid licence key" or a persistent connection error, contact support with your order number.
## Moving to a new site
If you're relaunching a site on a new domain (for example, moving from a staging URL to your live domain), your existing activation may need to be freed up first. Deactivate the license on the old domain (or from your account on the Dotjuice shop if the old site is no longer reachable), then activate it on the new one.

View File

@@ -0,0 +1,4 @@
{
"label": "Widgets",
"position": 2
}

View File

@@ -0,0 +1,32 @@
# ACF Frontend Form
Found in the Elementor panel under **Dotjuice → ACF Frontend form**. Requires Advanced Custom Fields (ACF).
## How it works
Place this widget on a template that renders a single post or page — it displays an editable form for **whichever post is currently being viewed**, using ACF's own native form rendering. This widget only works on singular posts/pages (a single product, a single post, a single custom post type entry); it doesn't render anything on archive pages, the homepage, or similar listing pages.
## Content settings
| Setting | What it does |
|---|---|
| **ACF Field Groups** | Choose which of your site's ACF field groups should be editable in this form. Nothing renders until at least one is selected. |
| **Enable Title** | Includes the post title as an editable field. |
| **Enable Content** | Includes the main content editor as an editable field. |
| **Submit Button Label** | The text on the form's submit button (default "Update"). |
## Setting it up
1. Place the widget on a Single Post, Single Product, or other singular template in your Elementor Theme Builder.
2. Select the ACF field group(s) you want editable.
3. Decide whether the post title and/or content should be editable too.
4. Publish and test by viewing an actual individual post/page that uses this template.
## ⚠ Important: this widget has no built-in access restriction
Anyone who can view the page this widget is placed on can submit changes through the form — there's no automatic login requirement or capability check. If you only want logged-in users, specific roles, or the post's author to be able to edit, you'll need to add that restriction yourself: placing the widget inside a members-only page, using a membership/restriction plugin, or a conditional visibility rule in Elementor Pro. Don't place this widget on a fully public page unless open editing is genuinely what you want.
## Good to know
- This widget only renders a form when viewing an actual singular post or page — on archives, the homepage, or search results, it won't display anything.
- The uploader for image/file fields uses a simple file picker rather than the full WordPress media library browser.

View File

@@ -0,0 +1,27 @@
# Woo Add Product Tab
Found in the Elementor panel under **Dotjuice → Woo Add Product Tab**. Requires WooCommerce.
## How it works
Place this widget on your Single Product template — it adds one additional tab to WooCommerce's existing native tabs (Description, Additional Information, Reviews), styled to match them automatically since it uses WooCommerce's own tab system.
## Content settings
| Setting | Default | What it does |
|---|---|---|
| **Tab Title** | "Additional Info" | The tab's label. |
| **Tab Content** | — | Rich-text content shown inside the tab. |
| **Tab Order** | 50 | Controls where this tab sits relative to WooCommerce's defaults (Description = 10, Additional Information = 20, Reviews = 30). The default of 50 places it after Reviews — lower numbers move it earlier in the tab order. |
## Setting it up
1. Add the widget to your Single Product Elementor Theme Builder template.
2. Set your tab title and content.
3. Adjust Tab Order if you want it positioned somewhere other than last.
## Good to know
- **If this widget is placed on a shared Single Product template** (which is the normal way to use Elementor Theme Builder — one template applying to every product), every product using that template shows the **identical** tab title and content. This widget doesn't support per-product dynamic content — if you need different tab content on different products, you'll need [ACF Frontend Form](acf-frontend-form.md) with a custom field, or a separate template per product.
- Only one tab per widget instance — add a second instance of this widget if you need two extra tabs.
- You won't see this tab live in the Elementor editor canvas — a placeholder note explains this; preview it by viewing an actual product page on the front end.

View File

@@ -0,0 +1,44 @@
# Woo Cart
Found in the Elementor panel under **Dotjuice → Woo Cart**. Requires WooCommerce (does not require Elementor Pro).
## How it works
Place this widget on your Cart page template. It renders your shopper's current cart — items, coupon box, and totals — built independently of WooCommerce's default cart template, so it's fully restyled from the ground up.
## Layout settings
| Setting | Default | What it does |
|---|---|---|
| **Desktop Layout** | 2 columns | Two columns (cart items beside the totals panel) or one column (stacked). |
| **Totals Column Width** | 340px | Two-column layout only — the width of the totals sidebar. |
| **Gap Between Columns** | 32px | Spacing between the two columns. |
| **Show Coupon Field** | On | Displays the coupon code box. Only actually appears if your store's own WooCommerce settings have coupons enabled — if you've disabled coupons store-wide, this setting has no effect. |
| **Show Update Cart Button** | On | See below — this controls how quantity changes are handled. |
## Instant AJAX updates vs. the Update Cart button
This is the most important setting on this widget, so it's worth understanding both modes:
**With "Show Update Cart Button" on (default):** shoppers change a quantity, then click a visible **Update Cart** button (which stays disabled until something has actually changed) to apply it — a standard, familiar cart flow with a normal page action.
**With "Show Update Cart Button" off:** there's no button at all. Instead, changing any quantity automatically updates that row's subtotal and the whole totals panel via AJAX, a fraction of a second after the shopper stops adjusting it — no page reload, no button click needed. This is the more modern, "instant" feeling option.
Choose whichever fits your store's style — both are fully functional, it's a matter of preferred shopping experience.
## Setting it up
1. Add the widget to your Cart page Elementor Theme Builder template.
2. Choose your column layout and decide on AJAX vs. button-based quantity updates.
3. Work through the style sections below to match your store's design.
4. Test by adding a product to your cart and viewing the page as a real shopper would.
## Styling
Extensive styling is available: **Cart Item** rows, **Thumbnail**, **Product Name** (including variation details), **Price/Quantity/Subtotal** (including the quantity stepper's plus/minus buttons), **Remove Button**, **Buttons** (a shared style applying to the coupon Apply button, the Update Cart button, and the Checkout button together), **Form Fields** (the coupon input and quantity field), **Products Box** (the card containing your item rows), **Coupon Box**, and **Totals Box**. If you use the Printful shipping plugin, an additional style section for its shipping calculator appears automatically.
## Good to know
- **The "Checkout Button Text" field only affects the editor preview** — on the live cart page with real items, the checkout button's text comes from WooCommerce's own settings rather than this field. The button's *styling* (colour, padding, etc. from the shared Buttons section) does apply live — it's specifically the text on this one field that's preview-only. If you need to change the actual live checkout button text, that's done through WooCommerce's own settings rather than this widget.
- While your own cart is empty, the Elementor editor shows a sample two-item cart purely so you have something to style against — this never appears to real shoppers, who see a genuine "Your cart is empty" message with a link back to your shop.
- Removing an item is instant (AJAX) regardless of the Update Cart Button setting.

View File

@@ -0,0 +1,46 @@
# Woo Custom Product Tabs
Found in the Elementor panel under **Dotjuice → Woo Custom Product Tabs**. Requires WooCommerce.
## How it works
Place this widget on your Single Product template — it replaces WooCommerce's entire tabs area with a fully rebuilt, restyled version, including desktop tabs that automatically convert to an accordion on smaller screens.
**Only need to add one extra tab to WooCommerce's existing tabs, without a full rebuild?** See the lighter-weight [Woo Add Product Tab](woo-add-product-tab.md) instead.
## Content settings — Tabs
| Setting | Default | What it does |
|---|---|---|
| **Hide Tab Headings** | Off | Hides the heading text at the top of each tab panel (including WooCommerce's own "Reviews" heading). |
| **Hide Description / Hide Additional Information / Hide Reviews** | Off each | Fully removes that specific default WooCommerce tab — not just visually, it won't render at all. |
| **Custom Tabs** | Empty | A repeater — add as many extra tabs as you need, each with: **Title**, **Content Type** (Text Editor or Elementor Template), **Content** (rich text, for Text Editor), and **Template ID** (for Elementor Template — see below). |
| **Accordion Below (px)** | 768 | The screen width below which tabs switch to an accordion layout. 768 suits tablet-portrait and below, 480 suits mobile-only, and 0 disables the accordion entirely (always shows tabs). |
## Adding an Elementor Template as a custom tab
For a custom tab, choosing **Elementor Template** as the Content Type requires entering that template's numeric ID directly (rather than picking it from a list). To find it:
1. Go to **Templates → Saved Templates** in your WordPress admin (or wherever your Elementor template library lives).
2. Open the template you want to embed, or hover over it in the list.
3. The number in the edit URL (`post=1234`) or shown in your browser's address bar is the Template ID — enter that number into the field.
## Styling
**Tab Navigation** — background, spacing, alignment, divider styling, and Normal/Hover/Active states for each tab button (including a separate colour control for the active tab's bottom border, useful for either blending it into the panel or removing the divider line entirely).
**Panel** — background, typography, padding, border, and shadow for the content area beneath the tabs.
**Reviews** (hidden if you've turned off the Reviews tab) — review count heading, review card styling, avatar (with an option to hide it, size, and rounding), star rating colours, author/date text, review body text, an optional decorative quote mark, and full styling for the review submission form — its star picker, labels, input fields, and submit button.
## Setting it up
1. Add the widget to your Single Product Elementor Theme Builder template.
2. Decide which default tabs to keep, and add any custom tabs you need.
3. Set your Accordion breakpoint based on how your theme handles tablets — 768px is a safe default for most sites.
4. Style the Tab Navigation and Panel sections to match your design, then move on to the Reviews section if you display product reviews.
## Good to know
- **If every tab ends up hidden**, nothing renders at all on the live product page — double check at least one tab (default or custom) is visible before publishing.
- Custom tab content using the Elementor Template option needs that template to already be built and published — this widget only embeds it, it doesn't create it.

View File

@@ -0,0 +1,55 @@
# Woo Product Filter
Found in the Elementor panel under **Dotjuice → Woo Product Filter**. Requires WooCommerce.
## How it works
This widget renders one or more filter groups (category, tag, brand, or attribute) and, by default, refreshes your product grid via AJAX whenever a shopper makes a selection — no full page reload needed. It's designed to sit on your Shop page or a category archive, alongside your product grid.
## Building your filter groups
Each filter group is one item in the **Filters** repeater. Add as many as you need — one per category/attribute you want shoppers to filter by.
| Setting | Default | What it does |
|---|---|---|
| **Filter Title** | Empty | An optional heading above this group. |
| **Filter By** | Category | Category, Tag, Brand, or Attribute. |
| **Taxonomy Slug** | — | Only for Attribute — the technical slug of the attribute (e.g. `pa_color`). |
| **Display Type** | List | List (simple clickable list) or Buttons (clickable button/swatch style). |
| **Match Logic** | Match Any | Whether selecting multiple terms in this group should show products matching *any* of them, or *all* of them. |
| **Show products without this attribute** | Yes | Attribute filters only. When a term is selected, decides whether products that don't have this attribute set at all stay visible (Yes) or are hidden (No). |
| **Enable Colour Swatches** | Off | Buttons display only. Shows each term's assigned colour as a clickable swatch instead of a text button — colours come from the [Product Attribute Colours](../../../../dotjuice-elementor-tools/documentation/user-guide/product-attribute-colours.md) settings page in the free plugin. Terms sharing the same colour are merged into a single clickable swatch. |
| **Show this filter** | Always | Always, only when any other filter is selected, or only when a specific other filter type has a selection — see "Dependent filters" below. |
| **Hide unavailable terms** | Off | When on, terms with zero matching products (given the current selection) are removed entirely rather than just visually faded. |
## Dependent filters
To build a filter group that only appears once another one is used — for example, showing a "Size" filter only after a category is chosen — set **Show this filter** to "When a specific filter is selected" and choose which filter type triggers it. If the triggering selection is cleared, the dependent group's own selections are cleared too.
## AJAX & URL settings
| Setting | Default | What it does |
|---|---|---|
| **Update products with AJAX** | On | Filters refresh the grid in place. Turning this off makes every filter selection a normal page navigation with the filter reflected in the URL instead. |
| **Live update** | Off | AJAX mode only. When on, the grid refreshes automatically the moment a filter is clicked. When off, shoppers make their selections and click an "Apply Filters" button to refresh. |
| **Update browser URL** | On | AJAX mode only. Keeps the URL in sync with the current filter selection as shoppers filter, so the page can be bookmarked, shared, or reloaded and show the same results. |
| **Products container selector** | Empty (auto-detect) | Advanced: the CSS selector of your product grid, if the widget doesn't auto-detect it correctly. Leave empty unless you're troubleshooting a grid that isn't updating. |
| **Contextual filtering** | Off | When placed on a category archive page, scopes filter options and counts to that category's products only, rather than your whole catalogue. |
## Styling
Filter Group headings, Buttons (Normal/Hover/Active states), Swatches (Normal/Selected states), and Faded terms (opacity, greyscale, scale for unavailable options, plus a toggle for whether faded/unavailable terms can still be clicked).
## Setting it up
1. Add the widget to your Shop page or category archive template, near your product grid.
2. Add a filter group for each way you want shoppers to filter — start with Category, then add Attribute groups for things like colour or size.
3. For colour attributes, set up your colours first on the [Product Attribute Colours](../../../../dotjuice-elementor-tools/documentation/user-guide/product-attribute-colours.md) page, then enable **Enable Colour Swatches** on that filter group.
4. Leave AJAX and URL settings at their defaults for most stores — instant, bookmarkable filtering.
5. Test: apply a filter, copy the URL, and open it in a new tab (or with JavaScript disabled) to confirm it reproduces the same filtered results.
## Good to know
- **Filtered URLs work even without JavaScript** — if a shopper shares a filtered link, or your page is cached, the filter still applies correctly on a plain page load, not just via AJAX. This is deliberate and doesn't need any extra setup.
- Colour swatches only work for **Attribute** filter groups (not category/tag/brand), and require colours to already be configured on the Product Attribute Colours page — a term with no colour assigned won't show a meaningful swatch.
- If your product grid doesn't refresh correctly after filtering, check the **Products container selector** field — leaving it empty works for most themes' standard WooCommerce/Elementor product grids, but an unusual custom grid layout may need this set explicitly.

View File

@@ -0,0 +1,34 @@
# Woo Quick View Popup
This widget renders the **content shown inside** a Quick View popup. It only works as part of the full Quick View setup — see [Woo Quick View](woo-quick-view.md) for the complete walkthrough if you haven't set this up yet.
Found in the Elementor panel under **Dotjuice → Woo Quick View Popup**. Requires WooCommerce.
## How it works
Place this widget inside an Elementor popup (nothing else needs to go in that popup — this widget fills it entirely). It renders as an iframe showing whichever product a shopper clicked a Quick View button for.
## Content settings
| Setting | Default | What it does |
|---|---|---|
| **Content Source** | Dedicated quick view page (recommended) | **Dedicated**: shows a clean, minimal view of the product — no theme header/footer — using either a template you choose below or a bare WooCommerce product layout. **Legacy**: shows your actual full product page inside the popup, with the option to hide the header/footer via the settings below. |
| **Quick View Template** | Empty (bare WooCommerce layout) | Dedicated mode only. Choose a specific Elementor template to control exactly how the product appears inside the popup, or leave empty to use a plain WooCommerce product layout. |
| **Hide Header** / **Hide Footer** | Off / Off | Legacy mode only. Hides your theme's header and/or footer from within the popup. |
There's no Style tab — the popup content always fills the popup completely; size it using the popup's own Width/Height settings in Elementor.
## Hiding specific elements inside the popup
Add the CSS class `hide-in-qv` to any element in your product template (or your real product page, in Legacy mode) that you don't want shown inside the popup — useful for hiding things like breadcrumbs or a related-products section that don't make sense in a compact popup view.
## Which mode should you use?
**Dedicated** (the default and recommended option) is faster and cleaner — it loads a minimal, purpose-built view rather than your entire themed page. Pair it with a purpose-built Elementor template under **Quick View Template** for full control over exactly what shoppers see.
**Legacy** is useful if you want the popup to look identical to your real product page without building a separate template — but it loads more (the full page, then hides parts of it), so it's a little slower to open.
## Good to know
- **This widget must be placed inside an actual Elementor popup**, and that popup must then be selected in the separate Woo Quick View button widget's settings — on its own, on a normal page, it does nothing.
- If you're using a custom **Quick View Template**, note that it replaces WooCommerce's own single-product layout entirely inside the popup — any customisations on your real product page template aren't automatically inherited, since it's a genuinely separate template.

View File

@@ -0,0 +1,40 @@
# Woo Quick View
Two widgets work together to build Quick View: **Woo Quick View** (this one — the trigger button) and **Woo Quick View Popup** (the content shown inside the popup). Both are needed; this guide covers the full setup.
Requires WooCommerce. **Requires Elementor Pro** for the popup to actually open — without Elementor Pro, the quick-view button gracefully falls back to a normal link straight to the product page instead, so nothing is ever broken, it simply won't show a popup.
## How it works, end to end
1. You build a popup (an Elementor Pro popup content type) containing the **Woo Quick View Popup** widget.
2. You place the **Woo Quick View** widget anywhere you like, and point it at that popup.
3. The Quick View widget then automatically injects a quick-view button onto every product in your product loops (grids, carousels) sitewide — you don't need to manually add a button to each product card.
## Setting it up
1. **Create the popup**: in Elementor, create a new Popup (Templates → Popups → Add New in your Elementor library).
2. **Add the Woo Quick View Popup widget** inside it — see [Woo Quick View Popup](woo-quick-view-popup.md) for its settings. Size the popup itself using Elementor's own popup Width/Height settings.
3. **Publish the popup.**
4. **Add the Woo Quick View widget** anywhere on your site (a header, a single instance on any page — it doesn't need to be near your product grid, since it works by injecting buttons into loops sitewide once enabled).
5. Turn on **Enable Quick View**, and select your popup under **Quick View Popup**.
6. Save and check a shop or category page — quick-view buttons should now appear on your product cards.
## Content settings
| Setting | Default | What it does |
|---|---|---|
| **Enable Quick View** | Off | The master switch — turns on automatic button injection into every product loop on your site. Nothing happens until this is on. |
| **Quick View on Looped Add to Cart** | Off | For variable products shown in a grid with a "Select options" link (common with Elementor Pro's Loop Grid), replaces that link with a quick-view button too — so shoppers can pick variations without leaving the grid. |
| **Hide on Mobile** | Off | Hides the quick-view button on smaller screens. |
| **Quick View Icon** | Eye icon | The icon used for the button. |
| **Quick View Popup** | — | Which popup contains your Woo Quick View Popup widget — this is the link between the two widgets. **Make sure to select an actual popup you've built with the Quick View Popup widget inside it** — this dropdown lists all your Elementor templates, not only popups, so double check you've selected the right one. |
## Styling
Button alignment, and Normal/Hover icon colour and size.
## Good to know
- **The button widget and the popup widget must both be set up for anything to happen** — placing just one without the other has no visible effect.
- Hovering over a quick-view button preloads the popup content in the background, so the popup opens close to instantly on click — this preloading only happens when your popup widget is set to its recommended "Dedicated" content mode (see [Woo Quick View Popup](woo-quick-view-popup.md)).
- Buttons keep appearing correctly even after a [Woo Product Filter](woo-product-filter.md) AJAX refresh swaps in new products — no extra setup needed if both widgets are on the same page.

View File

@@ -0,0 +1,5 @@
{
"label": "Elementor Tools (Free)",
"position": 2,
"link": { "type": "doc", "id": "dotjuice-elementor-tools/getting-started" }
}

View File

@@ -0,0 +1,42 @@
# Getting Started
## Requirements
Dotjuice Elementor Tools requires **Elementor** (the free page builder plugin) to be installed and active. It doesn't require WooCommerce or ACF, but several widgets only appear once those plugins are active too — see [Finding your widgets](#finding-your-widgets) below.
## Finding your widgets
Open any page in the Elementor editor and look for the **Dotjuice** category in the widgets panel on the left. Every widget from this plugin lives there.
If a widget you expect to see is missing:
- **All WooCommerce-related widgets** (anything with "Woo" in the name, plus **Woo Taxonomy List**) only appear once **WooCommerce** is installed and active — even Woo Taxonomy List, which can be used for non-shop content like blog categories, only shows up with WooCommerce present. If you want a general-purpose taxonomy list widget on a site without WooCommerce, install WooCommerce or get in touch with support.
- The **Image Carousel Transform** widget only has a visible effect on pages that also use Elementor Pro's native Image Carousel widget elsewhere.
## Where the plugin's settings live
In your WordPress admin menu, under **Dotjuice**:
- **Elementor Tools** — the plugin's own dashboard (Getting Started, Widgets overview, System Status, Support)
- **Screenshot API** — required setup for the Screenshot Capture widget (see [Screenshot API Settings](screenshot-api-settings.md))
- **WooCommerce Hacks** — account page tweaks and product attribute colours (only visible with WooCommerce active — see [WooCommerce Account Settings](woocommerce-account-settings.md) and [Product Attribute Colours](product-attribute-colours.md))
## Recommended first steps
1. If you plan to use **Screenshot Capture**, set up your API key first — see [Screenshot API Settings](screenshot-api-settings.md). The widget won't display anything without it.
2. If you run a WooCommerce store, review [WooCommerce Account Settings](woocommerce-account-settings.md) — most stores end up wanting at least one of these tweaks (hiding unused account tabs, excluding a category from the shop page).
3. Browse the widget guides below for the ones relevant to your build.
## Widget guides
- [Screenshot Capture](widgets/screenshot-capture.md)
- [Dark Mode Toggle](widgets/dark-mode-toggle.md)
- [Keyword Linker](widgets/keyword-linker.md)
- [Markdown Widget](widgets/markdown-widget.md)
- [Image Carousel Transform](widgets/image-carousel-transform.md)
- [Woo Add to Cart Transform](widgets/woo-add-to-cart-transform.md)
- [Woo Categories Transform](widgets/woo-categories-transform.md)
- [Extended Product Loop](widgets/extended-product-loop.md)
- [Woo My Account Transform](widgets/woo-my-account-transform.md)
- [Woo Page Numbers](widgets/woo-page-numbers.md)
- [Woo Taxonomy List](widgets/woo-taxonomy-list.md)

View File

@@ -0,0 +1,26 @@
# Product Attribute Colours
**Dotjuice → WooCommerce Hacks → Attribute Colours** (only visible with WooCommerce active)
## What this does
Lets you assign a hex colour to each term of any product attribute on your store (Colour, Material, or any custom attribute you've created). This is a configuration page — see the note below about where these colours are actually displayed.
## Setting a colour
1. Choose the attribute you want to configure from the dropdown at the top (e.g. "Colour").
2. Every term for that attribute is listed in a table, each with a colour picker and a matching hex code field — you can use either; they stay in sync.
3. Enter or pick a colour for each term you want to configure. A "Clear" button next to each row removes its colour.
4. Save.
## Sharing one colour across several terms
If several terms should display as the same swatch colour (for example, "Ash", "Carbon Grey", and "Slate" all rendering as the same grey), just give them the identical hex value. The table shows a "Shared" indicator next to terms that currently share a colour with others, so you can see at a glance which terms are grouped together.
## Sorting the list
Use the **Sort by** control (Name or Hex Value) to reorder the table while you work — sorting by hex value groups terms with the same colour together visually, useful for checking your "shared colour" groupings are set up the way you intended.
## ⚠ Where these colours actually appear
This page only **stores** the colour assignments — it doesn't display them anywhere on its own. To show them as clickable colour swatches on your product pages, you need the **Woo Add to Cart Transform** widget's "Show Colour Swatches" option, which is a [Dotjuice Elementor Tools Pro](../dotjuice-elementor-tools-pro/getting-started.md) feature. In the free version, you can fully configure your colours here ready for when you upgrade, but your product options will display as plain buttons rather than colour swatches until Pro is active.

View File

@@ -0,0 +1,29 @@
# Screenshot API Settings
**Dotjuice → Screenshot API**
This page configures the credentials the [Screenshot Capture](widgets/screenshot-capture.md) widget needs to function, and lets you manage the local cache of captured screenshots.
## Setting up your API key
1. Sign up for a Screenshot Machine account and get an API key (a link to their site is provided on the settings page).
2. Paste your **API Key** into the field and save. A warning banner at the top of the page will disappear once a key is saved.
3. If your Screenshot Machine account has a **Secret Key** configured for additional request security, enter it in the optional **Secret Key** field too — most accounts don't need this.
Until an API key is entered, every Screenshot Capture widget on your site will fail to display an image.
## Cache management
This section shows:
- How many screenshots are currently cached
- Their total size on disk
- Where they're stored (inside your uploads folder)
- A **Clear All Cached Screenshots** button
Clearing the cache deletes every cached screenshot file and removes the corresponding entries from your Media Library. Every widget will re-capture its screenshot (spending a fresh API call) the next time its page is viewed. Use this if you've made site-wide changes to target pages and want everything refreshed at once, rather than refreshing screenshots one at a time from the editor.
## Things to know
- Every screenshot capture — whether from a visitor loading an uncached page, or your own manual refresh — counts as one billed API call against your Screenshot Machine plan. Keep this in mind if you have many Screenshot Capture widgets with a low or zero Cache Limit.
- The Secret Key field is optional and only relevant if you've specifically enabled request signing in your Screenshot Machine account settings.

View File

@@ -0,0 +1,4 @@
{
"label": "Widgets",
"position": 2
}

View File

@@ -0,0 +1,34 @@
# Dark Mode Toggle
Found in the Elementor panel under **Dotjuice → Dark Mode Toggle**.
## How it works
This widget renders a small clickable icon. Clicking it adds a dark-mode class to your entire site and swaps Elementor's four Global Color variables (Primary, Secondary, Text, Accent) to the dark-mode values you configure on the widget. It remembers the visitor's choice, so it stays applied on their next visit.
**Important:** this widget only changes colors for elements styled using Elementor's Global Colors. If part of your design uses a hardcoded color instead of a Global Color, that part won't respond to dark mode.
## Content settings
| Setting | Default | What it does |
|---|---|---|
| **Light Mode Icon** | Moon icon | The icon shown when the site is currently in light mode (click to switch to dark). |
| **Dark Mode Icon** | Sun icon | The icon shown when the site is currently in dark mode (click to switch back to light). |
| **Icon Color / Hover Color** | — | Styling for the toggle icon itself. |
| **Icon Size** | — | Responsive sizing for the toggle icon. |
## Dark Mode Colors (Style tab)
Four color fields — **Primary**, **Secondary**, **Text**, and **Accent** — define what your site looks like once dark mode is switched on. Set each to the dark equivalent of the matching Elementor Global Color. If you leave any of these blank, a sensible built-in dark default is used instead.
## Setting it up
1. Add the widget somewhere visible and consistent — a header or footer works well, so it's reachable from every page.
2. Under the Style tab, set your four Dark Mode Colors to a palette that works well as a dark theme.
3. Save and test: click the toggle on the live site and check that the elements using your Global Colors switch correctly.
## Good to know
- **Whichever toggle instance was clicked most recently determines the colors used site-wide.** If you place more than one Dark Mode Toggle widget with different color settings, the last one clicked "wins" for the whole site until another is clicked. For a single consistent dark mode, use the same color settings on every instance, or better, only place the widget in one shared location like your header.
- You can deep-link directly into dark mode by adding `?dark=0` to any URL (or `?dark=1`, `?dark=2`, etc. if there's more than one toggle instance on that specific page) — useful for sharing a dark-mode preview link.
- The dark mode choice is remembered per browser (not per WordPress account), so it persists across visits on the same device but doesn't follow a visitor between devices.

View File

@@ -0,0 +1,31 @@
# Extended Product Loop
Found in the Elementor panel under **Dotjuice → Extended Product Loop**. Requires WooCommerce.
## How it works
This widget renders its own product grid — separate from Elementor's or WooCommerce's native product loop widgets. It shows all your regular published products, plus an extra tile for every individual product variation that has a value set for the attribute you choose. Each tile shows that variation's own image, name, and price, linking through to the parent product page.
## Content settings
| Setting | Default | What it does |
|---|---|---|
| **Attribute Name** | `pa_color` | The attribute taxonomy to pull variations from, using its technical slug (WooCommerce attributes are typically prefixed `pa_`, e.g. `pa_color`, `pa_size`). |
There's no Style tab on this widget — the grid uses WooCommerce's standard product-grid CSS classes, so it inherits your theme's existing product grid styling.
## What to expect in the grid
If a product has three variations matching your chosen attribute (say, three colours), it can appear as **up to four tiles**: the parent product once, plus one tile per matching variation. This is intentional — it's what makes a "shop by colour" browsing experience possible — but it's worth knowing in advance so it doesn't look like a duplication bug when you first set it up.
**This widget's tiles show image, name, and price only** — no Add to Cart button, sale badges, or star ratings, since the grid is built independently of WooCommerce's standard loop template. Link the tile through to the product page for the full buying experience.
## Setting it up
1. Decide which attribute you want to browse by (commonly colour or size) and find its technical slug — check **Products → Attributes** in your WordPress admin, or look at the attribute's edit URL.
2. Enter that slug into **Attribute Name**.
3. Place the widget on a page and confirm the variation tiles appear as expected.
## Good to know
- If the attribute slug you enter doesn't exist on your store, the widget quietly falls back to showing only your regular product list — no error is shown, so double-check your spelling if variation tiles aren't appearing.

View File

@@ -0,0 +1,33 @@
# Keyword Linker
Found in the Elementor panel under **Dotjuice → Keyword Linker**.
## How it works
This widget doesn't display anything visible on the page itself — it works in the background, scanning your post and page content for the keywords you've defined and converting matching occurrences into links. Add it once to a template that renders post content (a Single Post or Single Page template), and it applies to every post/page using that template.
Matching happens inside paragraph and heading text only — text inside list items, tables, or other structural elements isn't scanned. Matching is whole-word and case-insensitive, and any text that's already part of an existing link is left alone.
## Content settings — Keyword Links
A repeater list; add one row per keyword you want linked.
| Setting | What it does |
|---|---|
| **Keyword** | The exact word or phrase to search for. Matches are whole-word only (so "cat" won't match "category") and case-insensitive. |
| **Link** | The destination URL, with options to open in a new tab and/or add a "nofollow" attribute. |
| **Bold** | Makes the generated link bold. |
| **Link All Occurrences** | If on, every matching occurrence on the page gets linked. If off, only the first few (see Max Links below). |
| **Max Links** | Only shown when "Link All Occurrences" is off. The maximum number of times this specific keyword gets linked per page (150, default 3). |
## Setting it up
1. Add the widget to a template that renders your post/page content (typically your Single Post or Single Page Elementor template — this is a "Theme Builder" style template in Elementor, not a specific individual post).
2. Add a row for each keyword you want automatically linked, with its destination URL.
3. Save and visit a post that contains one of your keywords — it should now appear as a link.
## Good to know
- **This widget needs to sit on a template that actually renders post content** — placing it on a page with no post content being displayed does nothing, since it works by intercepting WordPress's content output.
- The first occurrence of a keyword found in a matching heading or paragraph keeps its original capitalization in the resulting link — you don't need to match the exact case when defining the keyword.
- Links are only ever added inside `<p>` and heading tags — if your target text lives inside a list, table, or custom block markup, it won't be matched.

View File

@@ -0,0 +1,27 @@
# Markdown Widget
Found in the Elementor panel under **Dotjuice → Markdown**.
## How it works
The widget fetches the Markdown file you specify directly in the visitor's browser and converts it to HTML on the fly. Because the fetch happens in the browser, the source file needs to allow cross-origin requests — raw file URLs from GitHub (`raw.githubusercontent.com`) work well; a URL that isn't set up to allow this will fail to load, with a note in the browser's developer console.
## Content settings
| Setting | What it does |
|---|---|
| **Markdown File URL** | The direct URL to the raw Markdown file (not a formatted preview page — for GitHub, use the "Raw" file link, not the normal file view). |
## Styling
| Setting | What it does |
|---|---|
| **Text Color** | Sets the base text color for the rendered content. |
The Markdown is converted to plain semantic HTML (headings, paragraphs, lists, code blocks, links) with no additional classes — headings, code blocks, and other elements will take on whatever styling your theme already applies to those standard HTML tags. If you want the rendered Markdown to look a specific way, style it through your theme's typography settings for headings, lists, and `<pre>`/`<code>` blocks, since this widget doesn't apply its own detailed formatting beyond the base text color.
## Good to know
- **Use the raw file URL, not a formatted view.** For a GitHub file, click "Raw" on the file page and use that URL — the normal GitHub file-viewer page returns an HTML page, not the Markdown source, and won't render correctly.
- The content loads via JavaScript after the page loads, so it won't appear in "view source" — this is expected and doesn't affect what visitors see.
- If nothing appears, check your browser's developer console: the two most common causes are an incorrect URL (view page instead of raw file) or the source not allowing cross-origin requests from your domain.

View File

@@ -0,0 +1,40 @@
# Screenshot Capture
Found in the Elementor panel under **Dotjuice → Screenshot Capture**.
## Before you start: set up your API key
This widget uses the Screenshot Machine API to capture screenshots, which requires a free or paid API key from their service. Go to **Dotjuice → Screenshot API** in your WordPress admin and enter your key — the widget won't display anything until this is done. See [Screenshot API Settings](../screenshot-api-settings.md) for full setup details.
## Content settings
| Setting | Default | What it does |
|---|---|---|
| **URL** | — | The web address to screenshot. |
| **Refresh Screenshot** button | — | Editor only. Forces a brand-new capture immediately, bypassing the cache — use this after the target page has changed. |
| **Full Page** | Off | Captures the entire scrollable page rather than just the visible viewport. |
| **Cache Limit (days)** | 0 | How many days a captured screenshot stays cached before it's automatically re-captured on a visitor's page load. `0` means it's captured once and never automatically refreshed — use the Refresh button or clear the cache manually (see below) to update it. |
| **Device** | Desktop | Desktop, Tablet, or Phone — captures at that device's typical screen dimensions. |
| **Zoom** | 100% | Zoom level applied during capture, from 50% to 200%. |
| **Click Element** | Empty | A CSS selector (or comma-separated list) to click before the screenshot is taken — useful for dismissing a cookie banner or opening a menu first. |
| **Selector** | Empty | Crop the capture to a specific element on the target page, given as a CSS selector. |
| **Delay (ms)** | 3000 | How long to wait after the page loads before capturing — increase this for pages with animations or content that loads in after the initial page load. |
## Display settings (Style tab)
- **Width / Height** — the maximum size of the screenshot display area.
- **Website Link** — if set, clicking the screenshot goes to this URL instead of the page that was captured.
- **Show Lightbox** — opens the screenshot in a lightbox on click (only applies if Website Link is empty). Multiple Screenshot Capture widgets on the same page with this enabled become one swipeable lightbox gallery together.
- **Scroll Speed** — for full-page captures only: how fast the image auto-scrolls to reveal the whole page (lower is faster).
- **Border**, **Box Shadow**, **CSS Filters**, and a **Transform** popover (rotate, scale, offset, opacity) are available for both the normal and hover states, exactly like Elementor's native Image widget.
## Managing your screenshot cache
On the **Dotjuice → Screenshot API** settings page, a Cache Management panel shows how many screenshots are currently cached and their total size, with a **Clear All Cached Screenshots** button to force every screenshot on your site to be re-captured on next view. Screenshots are stored in your Media Library, so clearing the cache removes them from there too.
## Good to know
- **Every capture uses one API call**, whether triggered by a visitor's first view of an uncached page, or the editor's Refresh button. With Cache Limit set to 0 (the default), a given screenshot is only captured once — subsequent visitors see the cached version until you manually refresh it or your Cache Limit expires it.
- **The first visitor to an uncached page waits for the live capture** to complete before the page finishes loading. If you're about to publish a page with several uncached screenshots, visit it yourself first (or use the editor's Refresh button on each one) so the cache is warm before real visitors arrive.
- The editor never triggers an automatic capture while you're designing, specifically to avoid spending API calls while you work — you'll see a placeholder instead until you click Refresh.
- Changing **Cache Limit**, **Delay**, **Click Element**, or **Selector** on an already-cached screenshot won't take effect until you use the Refresh button — these settings affect how a new capture is taken, not the one already cached.

View File

@@ -0,0 +1,31 @@
# Woo Add to Cart Transform
Found in the Elementor panel under **Dotjuice → Woo Add To Cart transform**. Requires WooCommerce.
## How it works
Place this widget on your single product template (typically inside your Elementor Theme Builder's Single Product template, near where the product form appears). It finds WooCommerce's native variation `<select>` dropdowns on that page and converts them into a row of clickable buttons.
## Content settings
| Setting | Default | What it does |
|---|---|---|
| **Swap to Buttons** | Off | Turns on the dropdown-to-button conversion. Leave this off if you want to keep native WooCommerce dropdowns but still use the price/description styling controls below. |
| **Show Colour Swatches** | Off | **Pro feature.** In the free version, this setting has no visible effect — buttons always display as text. Colour swatches (each button showing its actual colour) require [Dotjuice Elementor Tools Pro](../../../../dotjuice-elementor-tools-pro/documentation/marketing/overview.md). |
| **Hide Labels** | Off | Hides the attribute name label (e.g. "Colour", "Size") next to each button group. |
| **Button Spacing** | 10px | Spacing between buttons within a group. |
## Styling
- **Buttons** — Normal and Selected states, each with text colour, background colour, typography, border, box shadow, and padding, plus a shared border radius.
- **Text** — typography and colour for the product price and short description.
- **Swatch** — sizing, padding, and border controls for colour swatches (only visible in the Pro version, where swatches actually render).
## Setting up colour swatches (Pro)
Even in the free version, you can pre-configure your swatch colours ready for when you upgrade: go to **Dotjuice → WooCommerce Hacks → Attribute Colours** and assign a colour to each attribute term (e.g. Red, Blue, Green). See [Product Attribute Colours](../product-attribute-colours.md) for the full guide. Once Pro is active and "Show Colour Swatches" is enabled, these assigned colours display automatically.
## Good to know
- **Two WooCommerce-wide behaviours are always active once this plugin and WooCommerce are both installed**, regardless of whether you've placed this widget on any page: WooCommerce's default "Clear" reset-selection link is replaced with this widget's version, and per-variation pricing is always shown (rather than only appearing when variations have different prices). These are intentional store-wide improvements, not something you need to configure per page.
- Because the button styling targets WooCommerce's variation markup directly rather than being scoped to just this widget, if a page shows more than one product form (for example, a quick-view popup alongside the main product), the same button styling applies to all of them.

View File

@@ -0,0 +1,36 @@
# Woo Categories Transform
Found in the Elementor panel under **Dotjuice → Woo Categories Transform**. Requires WooCommerce.
## How it works
Place this widget on any page that shows WooCommerce's product category tiles — typically your Shop page when it's set to display subcategories. It restructures the tile markup into styleable wrapper sections and applies the styling you configure below to every category tile on that page.
This widget has no Content tab — every setting lives under Style.
## Box styling
Border style, colour, width, radius, background colour, and padding for the overall category tile.
## Image styling
- **Overflow** — controls whether hover transforms are clipped to the image area or allowed to spill outside it.
- Border, radius, and — for Normal and Hover states separately — a Transform popover (rotate, scale, offset, opacity), Box Shadow, and CSS Filters.
## Content styling
- **Hide Product Count** — the product count badge is hidden by default; turn this off if you'd like the count shown.
- **Position** — Relative (sits naturally below the image) or Absolute (overlays directly on top of the image, positioned at the bottom).
- Font colour, background colour, an optional background blur effect (for a frosted-glass look behind overlaid text), padding, border, and box shadow.
## Setting it up
1. Add the widget to your Shop page (or wherever your category tiles are displayed).
2. For an overlay-style card, set Content Position to Absolute and add a background colour with some transparency, or enable the blur effect for a frosted look.
3. Configure hover effects under Image styling for a polished interactive feel.
## Good to know
- **Two things happen automatically once this plugin and WooCommerce are both active**: the tile markup restructuring (extra wrapper elements around each category tile) happens site-wide regardless of whether this widget is placed anywhere, but the actual **styling** only applies once you've placed the widget on the page showing those tiles.
- Styling isn't scoped to a single widget instance — placing the widget once styles every category tile shown on that page.
- The product count badge is **hidden by default** — if you expect to see a count and it's missing, check the "Hide Product Count" setting.

View File

@@ -0,0 +1,23 @@
# Woo My Account Transform
Found in the Elementor panel under **Dotjuice → Woo My Account Transform**. Requires WooCommerce.
## How it works
Place this widget on your My Account page template (typically inside your Elementor Theme Builder's My Account template). It detects buttons and links within the account content area and applies the styling you configure below.
## Styling
- **Button Style** — Normal and Hover states, each with text colour, background colour, border, border radius, and box shadow, plus shared typography and padding. Applies to account action buttons (e.g. form submit buttons, "Pay", "Cancel").
- **Link Style** — typography, plus Normal and Hover text colour, applied to order-table links: download links, product name links, and order number links.
## Setting it up
1. Add the widget anywhere inside your My Account page template.
2. Configure your button and link colours to match your site's branding.
3. Visit the My Account page while logged in (as a real customer account, since this only applies within the actual account content) to check the styling.
## Good to know
- **Styling applies across the whole My Account area on that page, not just near the widget** — you only need to place this widget once on your My Account template for it to take effect everywhere within it.
- You won't see live account content while editing in Elementor — the editor shows a placeholder instead, since there's no real logged-in account context inside the editor. Preview your changes by viewing the actual My Account page on the front end while logged in.

View File

@@ -0,0 +1,29 @@
# Woo Page Numbers
Found in the Elementor panel under **Dotjuice → Woo Page Numbers**. Requires WooCommerce.
## How it works
Place this widget on your Shop page or any product archive/category template, where it will show. It wraps WooCommerce's built-in pagination and applies the styling you configure.
This widget only shows real pagination when there's more than one page of results to paginate through — on a page with too few products to need pagination, it will render an empty space.
## Styling
There's no Content tab — every setting lives under Style:
- **Alignment** — left, centre, or right.
- **Typography** — font styling shared across all pagination links.
- **Normal / Hover** — text and background colour for regular page number links.
- **Active** — text and background colour for the current page indicator (styled separately, since it's not a clickable link).
- **Border** and **Padding** — spacing and border styling for each page number.
## Setting it up
1. Add the widget to your Shop page or a product category archive template.
2. Style the Normal, Hover, and Active states to match your site.
3. Preview on the live site with enough products to trigger real pagination — the Elementor editor shows a fixed example (pages 14) purely so you can preview your styling, which won't match your site's real page count.
## Good to know
- **The Elementor editor always shows a sample 4-page pagination** so you have something to style against — this is a preview aid only, not a reflection of your real page count. Check the actual front end to see your real pagination.

View File

@@ -0,0 +1,61 @@
# Woo Taxonomy List
Found in the Elementor panel under **Dotjuice → Woo Taxonomy List**.
**Note:** despite the "Woo" name, this widget works with any public taxonomy on your site — product categories, blog categories, tags, or a custom taxonomy — not just WooCommerce. It currently only appears in the widgets panel when WooCommerce is active; if you'd like to use it purely for blog categories on a site without WooCommerce, get in touch with support.
## Two display modes
**Flat mode** lists every term in the chosen taxonomy in one simple list — good for a straightforward "browse all categories" block.
**Hierarchical mode** (the default) lets you choose specific parent terms, and displays each one with its child terms nested beneath — good for a "Shop by Category" style block where you want to group related subcategories under their parent.
## Content settings — Widget Heading
| Setting | What it does |
|---|---|
| **Heading Text** | An optional title shown above the list. |
| **Heading URL** | If set (and Heading Text is filled in), makes the heading a clickable link. |
| **Heading Tag** | The HTML tag used for the heading (H2H6, or a plain div), for correct document structure. |
## Content settings — List Settings
| Setting | Default | What it does |
|---|---|---|
| **Taxonomy** | Product categories | Which taxonomy to pull terms from — every public taxonomy registered on your site is available here. |
| **Show All Terms (Flat)** | Off | Switches to flat mode (see above). |
| **Parent Terms** | — | Hierarchical mode only. Choose which parent term(s) to display, each with its children listed beneath. |
| **Show Parent Term** | On | Hierarchical mode only. Shows the parent term itself as a clickable heading above its children. |
| **Max Depth** | 1 level | Hierarchical mode only. How many levels of nested children to show beneath each parent — 1, 2, 3, or all levels. |
| **Hide Empty Terms** | On | Excludes terms with no posts or products assigned to them. |
| **Order By** | Name | Name, Count, Slug, or Term ID. |
| **Order** | Ascending | Ascending or descending. |
## Content settings — Display
| Setting | What it does |
|---|---|
| **Show Term Count** | Adds a post/product count in brackets after each term name. |
| **List Icon** | An optional icon (as a CSS icon class, e.g. from Font Awesome) shown before each term link. |
## Styling
Extensive styling is available, organised into: **Heading** (typography, colour, spacing), **List Container** (padding, background, border, shadow), **Parent Items** and **Parent Link Text** (hierarchical mode only), **List Items** (marker style — none, disc, circle, square, numbers, or letters — spacing, indentation, background, and hover background), **Link Text** (typography, colour, hover underline), and **List Icon** (size, colour, spacing) if you've set one.
## Setting it up
**For a flat list** (e.g. "all blog categories"):
1. Choose your Taxonomy.
2. Turn on **Show All Terms (Flat)**.
3. Style as needed.
**For a grouped list** (e.g. "Shop by Category" with subcategories):
1. Choose your Taxonomy.
2. Leave Flat mode off, and select your parent term(s) in **Parent Terms**.
3. Set **Max Depth** to however many levels of children you want shown.
4. Style as needed.
## Good to know
- **If your configuration doesn't resolve to any terms** (for example, hierarchical mode with no parent terms selected yet), the widget shows a helpful explanatory message while you're editing in Elementor — but shows nothing at all on the live front end. Always double-check your configuration is complete before publishing.
- The **Parent Terms** picker updates automatically to show terms from whichever taxonomy you've selected, but this live update only works while you're inside the Elementor editor.

View File

@@ -0,0 +1,32 @@
# WooCommerce Account Settings
**Dotjuice → WooCommerce Hacks → General** (only visible with WooCommerce active)
## Settings
| Setting | Default | What it does |
|---|---|---|
| **Hide Dashboard Tab** | Off | Removes the "Dashboard" entry from the My Account menu. |
| **Hide Downloads Tab** | Off | Removes the "Downloads" entry from the My Account menu — useful for stores that don't sell downloadable products. |
| **Auto Redirect to Orders** | Off | Sends customers straight to their Orders page instead of the generic Account dashboard when they visit My Account. **Requires "Hide Dashboard Tab" to also be enabled** — see below. |
| **Redirect After Logout** | Off | Sends customers to your site's homepage after logging out, instead of WooCommerce's default behaviour. |
| **Exclude Product Categories from Shop** | None selected | A checkbox tree of every product category on your store. Categories you check are hidden from your main Shop page and from that category's own archive page. |
## ⚠ "Auto Redirect to Orders" needs "Hide Dashboard Tab" enabled too
These two settings work together — Auto Redirect to Orders only takes effect when Hide Dashboard Tab is also switched on. If you enable Auto Redirect on its own and it doesn't seem to do anything, check that Hide Dashboard Tab is enabled as well.
## About excluding categories
Excluding a category here hides its products from:
- Your main Shop page
- That category's own archive page
It does **not** hide those products from search results or from other custom product displays elsewhere on your site (like related products, or a widget built to specifically show that category). This is intentional — it's meant for keeping a category out of general browsing, not hiding it from your store entirely.
## Setting it up
1. Enable whichever toggles match what you want changed.
2. If you want customers redirected straight to Orders, enable both **Hide Dashboard Tab** and **Auto Redirect to Orders** together.
3. For category exclusions, check the categories you want hidden from your Shop page in the tree, then save.

View File

@@ -0,0 +1,5 @@
{
"label": "Pagespeed",
"position": 4,
"link": { "type": "doc", "id": "dotjuice-pagespeed/getting-started" }
}

View File

@@ -0,0 +1,30 @@
# Advanced
**Dotjuice → Page speed → Advanced**
## What this tab controls
WordPress's Heartbeat API, XML-RPC, and WooCommerce script loading on non-shop pages.
## Settings
| Setting | Default | What it does |
|---|---|---|
| **WordPress Heartbeat API** | Optimise | Choose **Default** (WordPress's normal behaviour, checking in roughly every 15 seconds), **Optimise** (extends the interval — see below), or **Disable** (removes it entirely). Heartbeat powers autosave, post-locking ("someone else is editing this post") notices, and some plugins' live dashboard updates. |
| **Heartbeat Interval (seconds)** | 60 | Only used when Heartbeat is set to Optimise. How often it checks in — minimum 15 seconds, whatever you enter is used as the new interval. A longer interval means less background load but a longer delay before autosave/post-lock notices update. |
| **Disable XML-RPC** | Off | Stops your site responding to XML-RPC requests — the older remote-publishing protocol some legacy apps and (historically) some brute-force attack tools target. Only worth enabling if you don't use an app, service, or plugin that specifically requires XML-RPC (check before enabling; some SEO and cross-posting tools still rely on it). |
| **Disable WooCommerce Scripts on Non-Shop Pages** | Off | Stops WooCommerce's cart and general styling/scripts from loading on pages outside your shop and cart/checkout flow — see the warning below before enabling. |
## ⚠ Before enabling "Disable WooCommerce Scripts on Non-Shop Pages"
This is a genuinely useful setting for pages that have nothing to do with your shop, but check your **My Account** pages (order history, downloads, addresses) after enabling it — those pages rely on WooCommerce's own styling too, and if they look visibly broken after you turn this on, it's this setting. Test it and confirm your account pages still look right before leaving it enabled on a live site.
## Heartbeat: Optimise vs Disable
**Optimise** (the default) is the safer of the two active choices — it keeps all of WordPress's Heartbeat-dependent features working (autosave, post locking, live plugin dashboards) but checks in less frequently, cutting down on background requests without losing functionality.
**Disable** removes Heartbeat entirely. This means autosave-in-the-background and "someone else is currently editing this" warnings stop working, and any plugin whose live-updating dashboard widgets depend on Heartbeat will stop updating live. Only choose this if you're confident nothing on your site relies on it.
## About XML-RPC
Disabling XML-RPC here uses WordPress's own built-in mechanism to refuse XML-RPC requests — it doesn't hide or remove the `xmlrpc.php` file itself, it simply makes it respond that XML-RPC is turned off. If you need airtight blocking at the server level (rather than the WordPress application level), that typically needs a rule added at your web server or firewall instead.

View File

@@ -0,0 +1,45 @@
# Caching
**Dotjuice → Page speed → Caching**
## What this tab controls
Full-page HTML caching: whether pages are cached at all, whether mobile and desktop get separate cached copies, whether logged-in visitors are included, and how long a cached page stays valid before it's rebuilt.
## Settings
| Setting | Default | What it does |
|---|---|---|
| **Enable Page Caching** | On | Turns full-page caching on or off entirely. With this off, every other setting on this tab has no effect. |
| **Separate Cache for Mobile Devices** | On | Stores a distinct cached copy for mobile visitors, detected by user agent. Keeps this on if your theme shows different content or layout on mobile — otherwise mobile visitors could occasionally be served a desktop-cached page or vice versa. |
| **Cache Pages for Logged-in Users** | Off | See the warning below — this doesn't do what the label suggests. |
| **Cache Lifetime (seconds)** | 86400 (24 hours) | How long a cached page is considered fresh before it's automatically rebuilt. Minimum 300 seconds (5 minutes), maximum 30 days. |
## How caching stays up to date
You never need to manually clear the cache after normal editing. It happens automatically when you:
- Publish or update any post or page (only that page and your homepage are cleared — the rest of your cached site is untouched)
- Switch themes
- Update a plugin or WordPress core
The **Cache Lifetime** setting is a safety net on top of this — a maximum age for any cached page, in case something changes the page without triggering a normal WordPress save (a scheduled event, an external data feed, etc.).
## ⚠ About "Cache Pages for Logged-in Users"
This setting is easy to misread. WordPress admin/editor sessions are excluded from the fastest cache delivery paths regardless of this setting — that part is fixed and can't be turned off, which is exactly what you want (you should always see a live, uncached view of your own site while logged in).
What this toggle actually does is let a logged-in visit *contribute* to building the cache that anonymous visitors later see, on the rare occasions a logged-in request reaches a page that isn't already cached. **We recommend leaving this off** unless you have a specific reason to change it: if you're logged in as an editor or admin and your theme shows you anything personalised (an admin bar styling quirk, a "welcome back" message, draft content preview, etc.), enabling this risks that content being saved into the cache and shown to anonymous visitors afterward.
## Manually clearing the cache
Two ways to force every cached page to rebuild immediately:
- **Clear Cache** button in the Page speed settings toolbar
- **Clear Cache** button in your WordPress admin bar (visible on every page, front-end and admin) — this one also shows your current cache size and clears the combined CSS/JS files from the [CSS](css-optimisation.md) and [JavaScript](javascript-optimisation.md) tabs at the same time
Use this after making a change that automatic clearing wouldn't catch — a manual template edit, a change made outside the normal post/page editor, or simply to confirm you're looking at a fresh copy of a page while troubleshooting.
## For the fastest possible caching
See [Getting Started](getting-started.md) for the one-time `WP_CACHE` setup step — it enables the fastest of three delivery methods this plugin uses. Caching still works without it, just not at its absolute fastest.

34
docs/dotjuice-pagespeed/cdn.md Executable file
View File

@@ -0,0 +1,34 @@
# CDN
**Dotjuice → Page speed → CDN**
## What this tab controls
Rewriting your site's stylesheet and script URLs to point at a CDN hostname instead of your own server.
## Settings
| Setting | Default | What it does |
|---|---|---|
| **Enable CDN URL Rewriting** | Off | Turns URL rewriting on or off. |
| **CDN URL** | Empty | The hostname to rewrite asset URLs to (e.g. `https://cdn.yoursite.com`). The plugin doesn't check that this URL is reachable or correctly configured — make sure your CDN is already set up and serving your site's files before enabling this. |
| **Rewrite These Directories** | `wp-content, wp-includes` | Only URLs containing one of these path segments are rewritten — leaves this as-is unless you have a specific reason to narrow or widen it. |
## What this does and doesn't cover
This setting rewrites the URLs WordPress generates for enqueued stylesheets and scripts — the same files covered by the [CSS](css-optimisation.md) and [JavaScript](javascript-optimisation.md) tabs. It does **not** rewrite:
- Image URLs (`<img>` tags, background images set via CSS)
- Media Library files linked or embedded in post content
- Fonts referenced from inside a CSS file's own `@font-face` rules
If your goal is CDN delivery for your whole media library rather than just CSS/JS, you'll need a dedicated media-offload plugin, or your CDN provider's own integration, in addition to this setting.
## Setting it up
1. Confirm your CDN is already configured and correctly mirroring/proxying your site (this plugin doesn't set up the CDN itself — it only rewrites URLs to point at one that's already working).
2. Enter your CDN's hostname in **CDN URL**, including the `https://` prefix.
3. Enable **Enable CDN URL Rewriting** and save.
4. Clear your cache and check a page's source (or your browser's Network tab) to confirm stylesheet and script URLs now point at your CDN hostname and load correctly.
If assets fail to load after enabling this, double-check the CDN URL is exactly correct and that your CDN is actually serving the `wp-content`/`wp-includes` paths — a misconfigured CDN will show as broken styling or a console full of failed requests.

View File

@@ -0,0 +1,34 @@
# CSS
**Dotjuice → Page speed → CSS**
## What this tab controls
Minification and combining of your site's local stylesheets, optional asynchronous loading of the combined file, and manual exclusions for stylesheets that shouldn't be touched.
## Settings
| Setting | Default | What it does |
|---|---|---|
| **Minify CSS** | On | Strips comments and unnecessary whitespace from stylesheets. Safe on its own — the visual output is identical, just a smaller file. |
| **Combine CSS Files** | On | Merges your local stylesheets into a single cached file, in the correct dependency order, cutting down the number of separate requests the browser has to make. External stylesheets (Google Fonts, CDN-hosted resources) are always left as their own requests. |
| **Load Combined CSS Asynchronously** | Off | Removes the combined stylesheet from the render-blocking path — see the warning below before enabling. |
| **Critical CSS** | Empty | A block of CSS you provide, inlined directly into every page. Required if you enable asynchronous loading (see below). |
| **Remove Unused CSS (Experimental)** | Off | Not yet active in this version — enabling it currently has no effect. We'll update this guide when it ships. |
| **Exclude Handles or Filenames** | Empty | A comma-separated list of partial matches (stylesheet handle names or filenames) to skip entirely — useful for a plugin that behaves oddly when combined with others. |
## ⚠ Before enabling "Load Combined CSS Asynchronously"
This is the highest-impact CSS setting and also the one most likely to cause a visible problem if used without preparation. Removing the stylesheet from the render path means the browser paints the page *before* your CSS has loaded — if you haven't told it what the essential above-the-fold styling looks like, visitors will briefly see unstyled HTML (a "flash of unstyled content," or FOUC) before your CSS kicks in.
**Always set Critical CSS first.** This should be the minimum styling needed to render what's visible without scrolling: your body font and background colour, header, navigation, and hero section. A tool like a critical CSS generator (search for "critical CSS generator" — several free online tools exist) can produce this automatically by analysing your homepage.
**Test on a staging copy of your site first**, particularly if your site has several very different-looking page templates (a landing page vs. a blog post vs. a WooCommerce product page) — one block of critical CSS may not cover all of them equally well.
## Excluding a stylesheet
If a specific plugin's styling looks wrong after combining, add its stylesheet handle or filename to **Exclude Handles or Filenames**. You can find a stylesheet's handle using your browser's developer tools (Network tab, filter by CSS) — the filename usually gives it away, or check the plugin's own documentation.
## What's not affected
External stylesheets — Google Fonts served from `fonts.googleapis.com`, CDN-hosted libraries, anything not physically hosted on your own server — are never combined or minified. They're already optimised by whoever serves them, and combining them isn't possible across domains.

View File

@@ -0,0 +1,34 @@
# Database
**Dotjuice → Page speed → Database**
## What this tab controls
One-click and scheduled cleanup of database bloat: old post revisions, abandoned drafts, spam comments, expired cache entries, orphaned metadata, and full table optimisation.
## Manual cleanup
Each card shows a live count for its category. Click **Clean** on any card to run that cleanup immediately — the count updates in place once it's done, no page reload needed.
| Card | What it removes |
|---|---|
| **Post Revisions** | Every saved revision of every post and page. WordPress creates a new revision each time you save a draft, and by default never removes old ones — a frequently-edited page can accumulate dozens. |
| **Auto Drafts** | Posts WordPress auto-saved as blank drafts that were never actually published or intentionally saved (the "Auto Draft" entries you sometimes see if you open the editor and navigate away). Running this also sweeps up any leftover metadata from posts already deleted elsewhere. |
| **Spam Comments** | Comments already marked as spam by your spam filter — this doesn't touch legitimate comments, only ones already flagged. |
| **Transients** | Expired cached data that plugins temporarily store in your database (API responses, computed values, etc.) and were supposed to clean up themselves once expired, but often don't. Only expired entries are removed — anything still active and in use is left alone. |
| **Orphan Post Meta** | Metadata rows left behind after their parent post was deleted through some other means, with nothing left to clean them up. |
| **Optimise Tables** | Runs a table optimisation pass across your database, reclaiming space left behind by all the deletions above and rebuilding indexes for faster queries. Worth running after a large cleanup, or periodically as routine maintenance. |
## Scheduled cleanup
| Setting | Default | What it does |
|---|---|---|
| **Enable Scheduled Database Cleanup** | Off | Turns on automatic cleanup running in the background on the schedule you choose below. |
| **Remove Post Revisions / Auto Drafts / Spam Comments / Expired Transients** | All off | Choose which categories the scheduled cleanup handles automatically. Each is independent — enable only the ones you want running unattended. |
| **Cleanup Frequency** | Weekly | How often the scheduled cleanup runs: Daily, Weekly, or Monthly. |
Note that scheduled cleanup only covers the four categories above — **Orphan Post Meta** and **Optimise Tables** are manual-only actions, run them from the cards above whenever you'd like.
## Recommended approach
For most sites, weekly scheduled cleanup of revisions, drafts, and spam is a safe "set and forget" choice. Transients change more often and are generally safe to include too. Table optimisation is worth running manually every month or two, or right after your first big cleanup on a site that's accumulated years of bloat.

View File

@@ -0,0 +1,40 @@
# Getting Started
## Where to find the settings
After activating the plugin, go to **Dotjuice → Page speed** in your WordPress admin menu. Settings are organised into nine tabs: Caching, CSS, JavaScript, HTML, Images, Preload, CDN, Database, and Advanced.
Every toggle saves through a single **Save Settings** button in the top toolbar — changes aren't applied until you click it. A **Clear Cache** button sits next to it for whenever you want to force a fresh rebuild of every cached page.
## Sensible defaults
The plugin ships with the safest, most broadly compatible optimisations already switched on: page caching, mobile-aware caching, CSS/JS minification, CSS combining, JS deferring, HTML minification, emoji script removal, lazy loading, font-display swap, cache preloading after publish, and font preloading. These are the settings virtually every WordPress site benefits from with no downside.
Settings that carry more risk of visibly breaking a page if your theme or plugins do something unusual — CSS/JS combining across the board, async CSS loading, JavaScript delay-until-interaction, CDN rewriting — are left off by default so you can enable and test them deliberately.
## The one-time setup step: enabling the fast cache path
For the fastest possible caching (page loads served in milliseconds rather than tens of milliseconds), your site needs one line added to `wp-config.php`:
```php
define( 'WP_CACHE', true );
```
The plugin tries to add this automatically when you activate it. If it can't — for example because `wp-config.php` isn't writable by PHP on your hosting — you'll see a persistent notice in your admin dashboard with a **Retry automatically** button, or you can add the line yourself just above the `/* That's all, stop editing! */` comment.
**Your site works fine without this.** If the automatic fast path isn't available, caching still runs through a normal WordPress request — just a little slower than the bypass path. Nothing breaks; you simply don't get the absolute fastest response times until it's in place.
## Recommended first steps
1. **Leave the defaults as they are** for your first save — they're the safest baseline.
2. **Set your LCP image** on the Preload tab (see [Preload](preload.md)) — this is the single highest-impact five-minute change you can make for your PageSpeed score.
3. **Clear your cache and reload your site** in an incognito/private window to confirm everything looks right.
4. **Work through the optional tabs one at a time** — CSS async loading and JS delay give the biggest additional speed gains but are worth testing on staging first if your site is complex (see the warnings in [CSS Optimisation](css-optimisation.md) and [JavaScript Optimisation](javascript-optimisation.md)).
## If something looks broken after enabling a setting
Every optimisation on this plugin can be switched off individually. If a page looks wrong after a change:
1. Click **Clear Cache** (top toolbar or the button in your WordPress admin bar) and reload — a stale cached page is the most common cause of "it looks broken."
2. If it's still wrong, turn off the most recently changed setting and clear the cache again.
3. See [Troubleshooting](troubleshooting.md) for the settings most likely to cause visible issues and what they need to work safely.

View File

@@ -0,0 +1,26 @@
# HTML
**Dotjuice → Page speed → HTML**
## What this tab controls
HTML minification, removal of unnecessary version query strings and default WordPress scripts, Google Fonts display behaviour, and DNS prefetch hints.
## Settings
| Setting | Default | What it does |
|---|---|---|
| **Minify HTML Output** | On | Strips HTML comments and collapses extra whitespace in your page's final output. Code inside `<script>`, `<style>`, `<pre>`, and `<textarea>` tags is left untouched, and browser-specific IE conditional comments are preserved. |
| **Remove Version Query Strings from Assets** | On | Strips the `?ver=6.7`-style query string WordPress appends to your own local stylesheets and scripts. This doesn't reduce file size or request count on its own — its purpose is compatibility with hosting, proxy, or CDN configurations that don't cache URLs containing a query string. External assets are left untouched. |
| **Disable WordPress Emoji Scripts** | On | Removes the script WordPress loads on every page to support emoji rendering on older browsers that don't have native emoji support. All modern browsers render emoji natively, so this is safe to leave on for virtually every site. |
| **Disable oEmbed (WordPress embeds)** | Off | Removes the discovery markup and script WordPress uses to let *other* sites embed your content automatically, and to embed content (tweets, YouTube videos, etc.) that you've pasted as a bare URL into your own posts. Embeds you've already added to existing content keep working — this only stops the discovery/JS layer, not embeds already saved into your posts. |
| **Add font-display: swap to Google Fonts** | On | Adds `display=swap` to your Google Fonts stylesheet URL, so browsers show your text immediately in a system fallback font and swap to the web font once it's downloaded — rather than hiding the text entirely until the font arrives. Only applies to fonts loaded the standard WordPress way; a font hardcoded directly into your theme's template files isn't affected. |
| **DNS Prefetch Domains** | Empty | One domain per line (e.g. `//fonts.gstatic.com`). Tells the browser to resolve these domains' DNS in advance, shaving a small amount of latency off the first request to each one. Useful for third-party services your site depends on that aren't already covered automatically — see [Preload](preload.md) for the domains handled automatically. |
## When to enable "Disable oEmbed"
If you don't use WordPress's automatic embed feature (pasting a bare YouTube or Twitter/X URL on its own line to have it turn into an embedded player automatically) and you don't need other sites to be able to embed your posts, this is safe to enable and removes a small amount of unnecessary markup and script loading from every page.
## Note on Google Fonts
The `font-display: swap` setting only touches fonts loaded the way WordPress expects — through the standard style-loading system. If your theme or page builder hardcodes a `<link>` tag to Google Fonts directly in a template file, or loads fonts via a CSS `@import`, this setting won't reach it. Most themes and Elementor's own font loading work correctly with this setting.

View File

@@ -0,0 +1,24 @@
# Images
**Dotjuice → Page speed → Images**
## What this tab controls
Lazy loading of images and iframes, and automatic width/height attributes to prevent layout shift.
## Settings
| Setting | Default | What it does |
|---|---|---|
| **Lazy Load Images** | On | Adds native browser lazy loading to images below the fold, using the standard `loading="lazy"` attribute — no JavaScript library involved. Images already handled by another lazy-load plugin, marked as always-load, or that WordPress itself has already flagged as your highest-priority image (see below) are automatically skipped. |
| **Lazy Load Iframes and Videos** | On | Same native lazy loading applied to embedded iframes (YouTube embeds, maps, and similar). |
| **Add Missing Width and Height Attributes** | On | Scans images in your post/page content and adds explicit width and height where they're missing, so the browser can reserve the right amount of space before the image downloads — preventing the page from visibly jumping around as images load in (this is what Google's Cumulative Layout Shift metric measures). Only applies to images inside your actual post/page content; images in theme templates, widgets, or headers/footers aren't covered. |
| **Serve WebP Images (when available)** | Off | Not yet active in this version — enabling it currently has no effect. We'll update this guide when it ships. |
## How this connects to your LCP image
If you've set an **LCP Image URL** on the [Preload](preload.md) tab, that specific image is automatically excluded from lazy loading and instead forced to load with maximum priority — regardless of the Lazy Load Images setting above. You don't need to do anything extra here; setting the LCP image on the Preload tab is enough.
## Why native lazy loading
Older lazy-load techniques rely on JavaScript to detect scroll position and swap in a placeholder image, which adds its own script weight and can cause a visible blank flash before the real image appears. The `loading="lazy"` attribute used here is built into every modern browser, adds no extra script, and the browser itself decides the ideal moment to start fetching each image — typically well before it scrolls into view, so there's no visible delay.

View File

@@ -0,0 +1,40 @@
# JavaScript
**Dotjuice → Page speed → JavaScript**
## What this tab controls
Minification and combining of local scripts, deferred loading, delayed loading until user interaction, and manual exclusions.
## Settings
| Setting | Default | What it does |
|---|---|---|
| **Minify JavaScript** | On | Strips comments and unnecessary whitespace from scripts. If minifying a particular script would risk breaking it, the plugin automatically falls back to serving it unminified rather than risk broken code. |
| **Combine JavaScript Files** | Off | Merges eligible local scripts into a single file. jQuery, Elementor scripts, WordPress core scripts, payment processor scripts, and anything carrying page-specific data are automatically excluded and kept separate — see below. |
| **Defer JavaScript Loading** | On | Adds the browser's native `defer` behaviour to local scripts, so they download in the background and run only after the page's HTML has finished parsing, instead of blocking it. |
| **Delay JavaScript Until User Interaction** | Off | Holds external scripts back entirely until the visitor's first scroll, click, tap, or key press — see the warning below. |
| **Additional Exclude Handles or Filenames** | Empty | A comma-separated list of partial matches to exclude from combining, deferring, and delaying. |
## Already excluded automatically
You don't need to manually exclude these — the plugin recognises them and leaves them alone:
- jQuery and jQuery Migrate
- Elementor's own scripts
- WordPress core scripts (block library, polyfills, translation files)
- Any script with data attached via `wp_localize_script()` (this is how many plugins pass AJAX URLs and security tokens to their scripts — combining or delaying it would break that plugin)
- Payment processor scripts (Stripe, PayPal, and similar) — these are never delayed, since checkout flows often depend on them being ready immediately
- Detected webpack/module bundles, which can break if concatenated with unrelated code
## ⚠ Before enabling "Delay JavaScript Until User Interaction"
This is the most aggressive JavaScript setting and delivers the biggest gain in initial load speed, but it means anything relying on those scripts genuinely won't run until the visitor first interacts with the page — no scroll, click, or key press means no script execution. For most sites this is invisible (analytics, chat widgets, and marketing pixels don't need to fire in the first fraction of a second), but if you have a script that must run immediately for the page to work correctly, exclude it by handle or filename first, or test thoroughly before relying on this in production.
## Excluding a script
Same approach as CSS: find the script's handle or filename using your browser's developer tools, then add it to **Additional Exclude Handles or Filenames**. Do this if a specific plugin's functionality stops working after combining or delaying is enabled.
## A note on combining with page builders
If your site is built with Elementor or a similar builder, don't expect **Combine JavaScript Files** to reduce every script down to one file — builder and block scripts are deliberately excluded from combining to avoid runtime conflicts between JavaScript modules. This is intentional and keeps your site stable; the combining still helps for your theme's and simpler plugins' scripts.

View File

@@ -0,0 +1,34 @@
# Preload
**Dotjuice → Page speed → Preload**
## What this tab controls
Priority loading for your most important image, automatic cache warming after publishing, font preloading, and DNS/connection hints for third-party services.
## Settings
| Setting | Default | What it does |
|---|---|---|
| **LCP Image URL** | Empty | The direct URL of your Largest Contentful Paint image — see below, this is the single most effective setting on this tab. |
| **Preload Cache After Publish** | On | The moment you publish or update a post, the plugin visits that page itself in the background a few seconds later, so the cache is rebuilt and ready before a real visitor arrives. Only meaningful if [page caching](caching.md) is switched on. |
| **Preload Web Fonts** | On | Adds connection preconnect hints for Google Fonts if you use them, and preload hints for your site's own locally-hosted `.woff2` font files, so fonts start downloading as early as possible instead of being discovered only once the browser reaches the CSS that references them. |
| **Auto Prefetch Common Third-party Domains** | On | Automatically detects whether your site actually loads from Google Fonts, Google Analytics, Google Tag Manager, Facebook, or jsDelivr, and adds a DNS prefetch hint only for the ones genuinely in use — so the browser resolves those domains' DNS in advance without wasting lookups on services you don't use. |
| **Preconnect Origins** | Empty | One origin per line (e.g. `https://api.example.com`) for any other third-party service your site depends on that isn't covered automatically above. Opens the connection (DNS + TLS handshake) in advance of the first real request to that origin. |
| **Preload from Sitemap** button | — | Visits every URL listed in your `sitemap.xml` in the background, warming the cache for your entire site in one go. |
## Setting your LCP image — the highest-impact five minutes you'll spend
Your **Largest Contentful Paint** score — one of the three Core Web Vitals Google uses for ranking and reports directly in PageSpeed Insights — is almost always determined by one specific image: your hero banner, or whatever the single largest visible element is when a page first loads.
1. Find the image you consider your "hero" for a page (or use the same one for a template that repeats across many pages).
2. Right-click it in your browser and copy its image address, or find its URL in the Media Library.
3. Paste that URL into **LCP Image URL**.
This does two things automatically: it tells the browser to fetch that specific image with maximum priority instead of waiting to discover it, and it also excludes that exact image from [lazy loading](images.md) — so the two settings never work against each other.
## Warming your whole site at once
If you're setting this plugin up on a site that already has a lot of published content, click **Preload from Sitemap** after saving your settings. This visits every URL in your sitemap so the cache is ready for real visitors immediately, rather than each page only being cached the first time someone happens to land on it.
For a smaller site this finishes in moments; for a very large site with thousands of URLs, expect it to take a while, since every page is visited individually to build its cache.

View File

@@ -0,0 +1,39 @@
# Troubleshooting
## A page looks broken after enabling a setting
1. Click **Clear Cache** and reload the page — a stale cached copy from before your change is the most common cause.
2. If it's still wrong, identify the most recently changed setting and turn it off, then clear the cache again to confirm that was the cause.
3. Check the notes below for the settings most likely to cause a visible issue.
## Settings most likely to need attention if something looks wrong
| Setting | Tab | What to check |
|---|---|---|
| **Load Combined CSS Asynchronously** | CSS | Causing a flash of unstyled content? You need Critical CSS filled in — see [CSS Optimisation](css-optimisation.md). |
| **Combine JavaScript Files** / **Delay JavaScript Until User Interaction** | JavaScript | A feature stopped working? Find its script's handle or filename in your browser's developer tools and add it to the exclude field. |
| **Disable WooCommerce Scripts on Non-Shop Pages** | Advanced | My Account page (orders, downloads) look unstyled? This is the setting — check it isn't excluding those pages incorrectly for your theme. |
| **Cache Pages for Logged-in Users** | Caching | Seeing content meant only for logged-in users appear for anonymous visitors? Turn this off and clear the cache. |
| **WordPress Heartbeat: Disable** | Advanced | Autosave or "someone else is editing this" notices stopped working? Switch back to Optimise instead of Disable. |
## "Add define('WP_CACHE', true) to your wp-config.php" notice won't go away
The plugin tries to add this automatically when activated. If your hosting doesn't allow it to write to `wp-config.php`, you'll see this notice with a **Retry automatically** button. If retrying doesn't clear it, add the line yourself:
```php
define( 'WP_CACHE', true );
```
Place it above the `/* That's all, stop editing! */` line near the bottom of `wp-config.php`. Your site caches correctly either way — this notice is about reaching the *fastest* of three delivery methods, not about caching being broken.
## Cache directory not writable
If you see a notice that `wp-content/cache/` isn't writable, your hosting needs that directory (and the plugin's subfolder within it) set to permission 755. Most hosts allow this by default; shared hosting with unusually strict permissions occasionally needs it set manually via your file manager or hosting support.
## A specific plugin or theme feature stopped working
Most compatibility issues trace back to combined CSS/JS. Add the affected stylesheet or script to the **Exclude Handles or Filenames** field on the relevant tab ([CSS](css-optimisation.md) or [JavaScript](javascript-optimisation.md)) rather than turning combining off entirely — this keeps the optimisation for everything else while carving out the one exception you need.
## Before uninstalling
Clear your cache manually first, and if you've been using the automatic `WP_CACHE` setup, you may want to remove `define( 'WP_CACHE', true );` from `wp-config.php` yourself afterward — uninstalling the plugin doesn't automatically remove that line.

16
docs/intro.md Normal file
View File

@@ -0,0 +1,16 @@
---
slug: /
sidebar_position: 1
---
# Dotjuice Plugin Documentation
Guides for installing, configuring, and getting the most out of every Dotjuice WordPress plugin.
## Plugins
- **[Elementor Tools (Free)](./dotjuice-elementor-tools/getting-started.md)** — screenshot capture, dark mode, WooCommerce styling widgets, and small utilities for Elementor.
- **[Elementor Tools Pro](./dotjuice-elementor-tools-pro/getting-started.md)** — advanced WooCommerce widgets: AJAX filtering, cart, quick view, custom product tabs, and ACF frontend forms.
- **[Pagespeed](./dotjuice-pagespeed/getting-started.md)** — full-page caching, CSS/JS optimisation, image loading, and database cleanup.
Looking for what each plugin does rather than how to configure it? Visit [dotjuice.co.uk](https://dotjuice.co.uk) for feature overviews and pricing.

4
site/.dockerignore Normal file
View File

@@ -0,0 +1,4 @@
node_modules
build
.docusaurus
.git

20
site/.gitignore vendored Normal file
View File

@@ -0,0 +1,20 @@
# Dependencies
/node_modules
# Production
/build
# Generated files
.docusaurus
.cache-loader
# Misc
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local
npm-debug.log*
yarn-debug.log*
yarn-error.log*

15
site/Dockerfile Normal file
View File

@@ -0,0 +1,15 @@
FROM node:20-alpine
WORKDIR /app
# Installed as its own layer so it's only re-run when package.json actually changes.
COPY package.json ./
RUN npm install --no-audit --no-fund
# Copy the rest of the scaffolded Docusaurus project (config, src/, static/).
# The docs/ folder copied here is only a placeholder — docker-compose.yaml
# bind-mounts the real markdown content from ../docs over the top of it at
# container start, so editing docs never requires rebuilding this image.
COPY . .
EXPOSE 3000

43
site/README.md Normal file
View File

@@ -0,0 +1,43 @@
# Website
This website is built using [Docusaurus](https://docusaurus.io/), a modern static website generator.
## Installation
```bash
npm install
```
**Note**: feel free to use the package manager of your choice.
## Local Development
```bash
npm run start
```
This command starts a local development server and opens up a browser window. Most changes are reflected live without having to restart the server.
## Build
```bash
npm run build
```
This command generates static content into the `build` directory and can be served using any static contents hosting service.
## Deployment
Using SSH:
```bash
USE_SSH=true npm run deploy
```
Not using SSH:
```bash
GIT_USER=<Your GitHub username> npm run deploy
```
If you are using GitHub Pages for hosting, this command is a convenient way to build the website and push to the `gh-pages` branch.

1
site/docs/.gitkeep Normal file
View File

@@ -0,0 +1 @@
This folder is overlaid by the bind-mounted ../../docs/ directory at runtime — see docker-compose.yaml.

115
site/docusaurus.config.js Normal file
View File

@@ -0,0 +1,115 @@
// @ts-check
import {themes as prismThemes} from 'prism-react-renderer';
// This runs in Node.js - Don't use client-side code here (browser APIs, JSX...)
// SITE_URL is read from the container's environment (see ../.env) so the
// production domain can be set in one place without editing this file.
const siteUrl = process.env.SITE_URL || 'http://localhost:3000';
/** @type {import('@docusaurus/types').Config} */
const config = {
title: 'Dotjuice Docs',
tagline: 'Documentation for the Dotjuice WordPress plugins',
favicon: 'img/favicon.ico',
future: {
v4: true, // Improve compatibility with the upcoming Docusaurus v4
},
url: siteUrl,
baseUrl: '/',
organizationName: 'dotjuice',
projectName: 'dotjuice-docs',
// 'warn' rather than 'throw': a broken cross-link (e.g. while a doc is
// being edited) logs a build warning instead of taking the whole site down.
onBrokenLinks: 'warn',
onBrokenMarkdownLinks: 'warn',
i18n: {
defaultLocale: 'en',
locales: ['en'],
},
presets: [
[
'classic',
/** @type {import('@docusaurus/preset-classic').Options} */
({
docs: {
sidebarPath: './sidebars.js',
routeBasePath: 'docs',
editUrl: undefined,
},
blog: false,
theme: {
customCss: './src/css/custom.css',
},
}),
],
],
themeConfig:
/** @type {import('@docusaurus/preset-classic').ThemeConfig} */
({
image: 'img/dotjuice-logo.png',
colorMode: {
respectPrefersColorScheme: true,
},
navbar: {
title: 'Dotjuice Docs',
logo: {
alt: 'Dotjuice',
src: 'img/dotjuice-logo.png',
},
items: [
{
type: 'docSidebar',
sidebarId: 'docsSidebar',
position: 'left',
label: 'Documentation',
},
{
href: 'https://dotjuice.co.uk',
label: 'dotjuice.co.uk',
position: 'right',
},
{
href: 'https://shop.dotjuice.co.uk',
label: 'Shop',
position: 'right',
},
],
},
footer: {
style: 'dark',
links: [
{
title: 'Plugins',
items: [
{label: 'Elementor Tools (Free)', to: '/docs/dotjuice-elementor-tools/getting-started'},
{label: 'Elementor Tools Pro', to: '/docs/dotjuice-elementor-tools-pro/getting-started'},
{label: 'Pagespeed', to: '/docs/dotjuice-pagespeed/getting-started'},
],
},
{
title: 'Dotjuice',
items: [
{label: 'Website', href: 'https://dotjuice.co.uk'},
{label: 'Shop', href: 'https://shop.dotjuice.co.uk'},
{label: 'Support', href: 'https://dotjuice.co.uk/support/'},
],
},
],
copyright: `Copyright © ${new Date().getFullYear()} Dotjuice Design.`,
},
prism: {
theme: prismThemes.github,
darkTheme: prismThemes.dracula,
},
}),
};
export default config;

45
site/package.json Normal file
View File

@@ -0,0 +1,45 @@
{
"name": "dotjuice-docs",
"version": "0.0.0",
"private": true,
"scripts": {
"docusaurus": "docusaurus",
"start": "docusaurus start",
"build": "docusaurus build",
"swizzle": "docusaurus swizzle",
"deploy": "docusaurus deploy",
"clear": "docusaurus clear",
"serve": "docusaurus serve",
"write-translations": "docusaurus write-translations",
"write-heading-ids": "docusaurus write-heading-ids"
},
"dependencies": {
"@docusaurus/core": "3.10.2",
"@docusaurus/faster": "3.10.2",
"@docusaurus/preset-classic": "3.10.2",
"@mdx-js/react": "^3.0.0",
"clsx": "^2.0.0",
"prism-react-renderer": "^2.3.0",
"react": "^19.0.0",
"react-dom": "^19.0.0"
},
"devDependencies": {
"@docusaurus/module-type-aliases": "3.10.2",
"@docusaurus/types": "3.10.2"
},
"browserslist": {
"production": [
">0.5%",
"not dead",
"not op_mini all"
],
"development": [
"last 3 chrome version",
"last 3 firefox version",
"last 5 safari version"
]
},
"engines": {
"node": ">=20.0"
}
}

15
site/sidebars.js Normal file
View File

@@ -0,0 +1,15 @@
// @ts-check
/**
* Sidebar is fully auto-generated from the docs/ folder structure, driven by
* each plugin's _category_.json for ordering and labels — add a new .md file
* anywhere under docs/ and it appears in the sidebar automatically, no
* manual entry needed here.
*
* @type {import('@docusaurus/plugin-content-docs').SidebarsConfig}
*/
const sidebars = {
docsSidebar: [{type: 'autogenerated', dirName: '.'}],
};
export default sidebars;

View File

@@ -0,0 +1,49 @@
import clsx from 'clsx';
import Link from '@docusaurus/Link';
import Heading from '@theme/Heading';
import styles from './styles.module.css';
const FeatureList = [
{
title: 'Elementor Tools (Free)',
to: '/docs/dotjuice-elementor-tools/getting-started',
description: 'Screenshot capture, dark mode, WooCommerce styling widgets, and small utilities for Elementor.',
},
{
title: 'Elementor Tools Pro',
to: '/docs/dotjuice-elementor-tools-pro/getting-started',
description: 'Advanced WooCommerce widgets: AJAX filtering, cart, quick view, custom product tabs, and ACF frontend forms.',
},
{
title: 'Pagespeed',
to: '/docs/dotjuice-pagespeed/getting-started',
description: 'Full-page caching, CSS/JS optimisation, image loading, and database cleanup.',
},
];
function Feature({title, to, description}) {
return (
<div className={clsx('col col--4')}>
<div className="text--center padding-horiz--md">
<Heading as="h3">
<Link to={to}>{title}</Link>
</Heading>
<p>{description}</p>
</div>
</div>
);
}
export default function HomepageFeatures() {
return (
<section className={styles.features}>
<div className="container">
<div className="row">
{FeatureList.map((props, idx) => (
<Feature key={idx} {...props} />
))}
</div>
</div>
</section>
);
}

View File

@@ -0,0 +1,11 @@
.features {
display: flex;
align-items: center;
padding: 2rem 0;
width: 100%;
}
.featureSvg {
height: 200px;
width: 200px;
}

39
site/src/css/custom.css Normal file
View File

@@ -0,0 +1,39 @@
/**
* Any CSS included here will be global. The classic template
* bundles Infima by default. Infima is a CSS framework designed to
* work well for content-centric websites.
*/
/* You can override the default Infima variables here. */
:root {
--ifm-color-primary: #25bec2;
--ifm-color-primary-dark: #25bec2;
--ifm-color-primary-darker: #25bec2;
--ifm-color-primary-darkest: #205d3b;
--ifm-color-primary-light: #25bec2;
--ifm-color-primary-lighter: #25bec2;
--ifm-color-primary-lightest: #25bec2;
--ifm-code-font-size: 95%;
--docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.1);
--ifm-footer-background-color: #111113 !important;
}
/* For readability concerns, you should choose a lighter palette in dark mode. */
[data-theme='dark'] {
--ifm-color-primary: #25bec2;
--ifm-color-primary-dark: #25bec2;
--ifm-color-primary-darker: #25bec2;
--ifm-color-primary-darkest: #25bec2;
--ifm-color-primary-light: #25bec2;
--ifm-color-primary-lighter: #25bec2;
--ifm-color-primary-lightest: #25bec2;
--docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.3);
--ifm-footer-background-color: #111113 !important;
}
/* Footer background: :root doesn't reach the footer because Infima's own
.footer--dark rule sets --ifm-footer-background-color directly on itself,
which always wins over an inherited value regardless of layers/order. */
.footer--dark {
--ifm-footer-background-color: #111113;
}

41
site/src/pages/index.js Normal file
View File

@@ -0,0 +1,41 @@
import clsx from 'clsx';
import Link from '@docusaurus/Link';
import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
import Layout from '@theme/Layout';
import HomepageFeatures from '@site/src/components/HomepageFeatures';
import Heading from '@theme/Heading';
import styles from './index.module.css';
function HomepageHeader() {
const {siteConfig} = useDocusaurusContext();
return (
<header className={clsx('hero hero--primary', styles.heroBanner)}>
<div className="container">
<Heading as="h1" className="hero__title">
{siteConfig.title}
</Heading>
<p className="hero__subtitle">{siteConfig.tagline}</p>
<div className={styles.buttons}>
<Link className="button button--secondary button--lg" to="/docs/">
Browse the Documentation
</Link>
</div>
</div>
</header>
);
}
export default function Home() {
const {siteConfig} = useDocusaurusContext();
return (
<Layout
title={siteConfig.title}
description="Documentation for the Dotjuice WordPress plugins.">
<HomepageHeader />
<main>
<HomepageFeatures />
</main>
</Layout>
);
}

View File

@@ -0,0 +1,23 @@
/**
* CSS files with the .module.css suffix will be treated as CSS modules
* and scoped locally.
*/
.heroBanner {
padding: 4rem 0;
text-align: center;
position: relative;
overflow: hidden;
}
@media screen and (max-width: 996px) {
.heroBanner {
padding: 2rem;
}
}
.buttons {
display: flex;
align-items: center;
justify-content: center;
}

View File

@@ -0,0 +1,7 @@
---
title: Markdown page example
---
# Markdown page example
You don't need React to write simple standalone pages.

0
site/static/.nojekyll Normal file
View File

BIN
site/static/img/dotjuice-logo.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

BIN
site/static/img/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB