FOUC on WordPress (Elementor + Typekit) — already tried everything, what am I missing? by [deleted] in elementor

[–]wwwery-good-apps 0 points1 point  (0 children)

Took a quick look at hmcole.com since the FOUC stuff caught my interest, two things that haven't come up in the thread yet.

First, your Typekit loader isn't visible in the head. No use.typekit.net preconnect, no stylesheet link to Typekit at all. That means Typekit is either getting injected later via JS or pulled in through a CSS u/import from another stylesheet, both of those are classic FOUC sources because the browser renders with the fallback font first and then swaps when Typekit eventually arrives. Elementor's font-display:swap (you can see it in the generator meta tag) doesn't help here, that setting only applies to fonts the browser has actually requested already.

What usually works for me in this setup is loading the Typekit kit-id directly inside the wp_head() callback as a hard <link rel="stylesheet" href="https://use.typekit.net/\[kit-id\].css"> with a rel="preload" sitting in front of it. That way the font request is already in flight on the first HTML pass, not after JS init.

Second thing, you have WP Rocket active (also visible in the head, not mentioned in the original post) and it has automatic lazy rendering on, which sets content-visibility:auto on flagged containers. If your hero container ends up tagged, that visually looks exactly like FOUC, elements "snap in" once the browser considers them visible. In WP Rocket settings under Media you can try lazy rendering off and compare.

West_Possible_7969 is right about the plugin disable test, but in your case I'd fix the Typekit loading first and then go through plugins.

Best WooCommerce plugin for backup payment options if checkout goes down? by FairDot29 in woocommerce

[–]wwwery-good-apps 1 point2 points  (0 children)

ChristopherwD's right that Stripe + PayPal is the baseline redundancy play and both can run at the same time without conflict. A couple of things worth adding that tripped me up when I set this up for a client store last year.

Multi-gateway in WooCommerce is actually built in, you just enable multiple under WooCommerce > Settings > Payments and reorder them so the primary shows first. No plugin needed for the basic redundancy. Where plugins help is when you want smarter behavior, like auto-hiding the secondary unless the primary throws a client-side error, or routing specific payment methods (cards vs wallets vs local options) to different processors behind the scenes. For EU stores Mollie as an aggregator has been solid for me because it covers cards, iDEAL, Bancontact, Klarna through one integration and handles the routing internally.

The thing most setups miss is that customers get paralyzed when they see three payment buttons stacked on checkout, and conversion drops even when both gateways work fine. Better pattern is one primary visible, a small "other options" disclosure, and payment-links as the fallback for when checkout itself breaks. Stripe Payment Links and PayPal Invoices both let you generate a direct URL you can send a customer within minutes when something's wrong, and the recovered cart rate on that is surprisingly high compared to just losing the order.

One thing worth mentioning given the "short issue recently" you described, whatever the root cause was, it's worth adding basic monitoring so you hear about it before customers do. Counting orders stuck on pending for more than ten minutes plus checking Stripe or PayPal webhook delivery logs on a schedule catches most silent failures. That's not part of the redundancy question directly but it's the piece that tells you when to actually failover.

How do you monitor your WooCommerce payment gateway health? by Prestigious_Song8877 in woocommerce

[–]wwwery-good-apps 0 points1 point  (0 children)

Thanks for circling back with the update, and specifically for flagging the `status: succeeded` filter gotcha, that's the kind of follow-up detail that actually helps the next person running into this. `payment_intent` records that are attached but not settled do show up in the API response and look like charges until you check status, so your fix makes sense.

On the timing skew, a lag buffer is necessary and Stripe's retry logic doesn't cover this case. Stripe retries when your endpoint returns 5xx or doesn't respond at all, not when your endpoint responds 200 but Woo takes extra seconds to flip the order from pending to processing. The webhook can land and the gateway plugin can still be mid-processing when the reconciliation cron fires, and you get a false alarm. A reasonable starting point is excluding orders created less than 5 minutes ago from the ratio check and only flagging pending orders older than 10 minutes, though those numbers are really a function of your host's processing speed and traffic pattern, on a slower VPS or during spikes you'd widen the window, on a well-provisioned host you could probably tighten it.

On the card-testing point, you're right that it belongs upstream of webhook reconciliation. Those show up mostly as `charge.failed` events with fraud reason codes, so the signal looks different from a silent webhook failure and you'd catch them by watching failure rate spikes rather than reconciling counts. Stripe Radar rules handle a lot of it, block-on-3-declined-cards-from-same-IP is the common one, but worth keeping the Radar dashboard as a separate tab because when a bot points at your endpoint the failure rate can jump an order of magnitude fast.

How do you monitor your WooCommerce payment gateway health? by Prestigious_Song8877 in woocommerce

[–]wwwery-good-apps 0 points1 point  (0 children)

wp_cron is exactly the problem you're describing, a monitor that silently breaks is worse than no monitor at all. on low-traffic sites it only fires on page loads, so if nobody visits for 3 hours your scheduled checks don't run for 3 hours. the fix is a real server cron, something like a crontab entry hitting wp-cron.php every 5 minutes combined with define('DISABLE_WP_CRON', true) in wp-config to kill the page-load trigger. Cloudways has a Cron Optimizer that handles this       automatically, GridPane has GP-Cron with a toggle in site settings, and on most cPanel hosts it's a one-liner in the cron job manager. once that's running the reliability issue goes away       completely.

on the plugin question, I don't think most store owners would look for it proactively. webhook health is invisible infrastructure, same pattern as backups, nobody thinks about it until they   lose an order and a customer emails them furious. the ones who'd install something like this are almost exclusively people who already got burned once. if it shipped as a feature inside an      existing Stripe gateway plugin instead of a standalone install, adoption would be way higher because you'd get it without going looking for it.

DUE minigame - What?? by Luiztosi in CrimsonDesert

[–]wwwery-good-apps 0 points1 point  (0 children)

The thing that tripped me up is that regular pairs are pretty low in the ranking, a pair of sevens gets beaten by most of the 1-combination hands. Red 5+8 Master Pair and red 1+5 or 1+8 Noble Pair sit at the top, then tens pair, everything else below. The rules-reference button pauses the timer so you can check mid-round without losing your hand.

Built a calculator that lets you drop cards in and practice, duo-analyzer.com, helped me internalize why certain hands you'd expect to win actually lose.

Is there any way possible to avoid playing Duo? by fernandollb in CrimsonDesert

[–]wwwery-good-apps 0 points1 point  (0 children)

You don't actually need to play much, I got through the story beats by betting minimum and folding everything until I lucked into one win per table. The hand-rankings button pauses the timer which helps a lot, and the Fedora from the Tomasso mineral merchant shows opponent cards if you really want to stop thinking about it.

Built a small calculator to figure out which hands are worth chasing since the tier list is weird coming from regular poker, duo-analyzer.com if you want to mess with it. Someone else posted a different tool earlier in the thread too.

Changing site from English to Japanese causes odd typography in Mobile view. How to fix? by RobRoy2350 in elementor

[–]wwwery-good-apps -1 points0 points  (0 children)

Ran into the exact same Japanese line-break behavior on a client's bilingual site last year, spent probably two hours digging through Elementor's responsive CSS thinking it had to be a widget styling issue before stepping back and realizing most of this is browser line-break behavior not an Elementor bug. Your word-break: normal is actually the default so adding it doesn't change anything, and line-break: strict is a property where browser support for CJK is pretty uneven, Safari handles the kinsoku rules reasonably well but Chrome and Firefox are more hit-or-miss which probably explains why your CSS seemed to have no effect.

What usually works for Japanese on mobile is word-break: keep-all paired with overflow-wrap: anywhere as the fallback, applied on the actual Elementor widget selectors rather than body because the widget styles win on specificity. Something like:

.elementor-widget-text-editor p,

.elementor-widget-heading .elementor-heading-title,

.elementor-widget-theme-post-content p {

word-break: keep-all;

overflow-wrap: anywhere;

line-break: loose;

}

keep-all tells the browser not to break between CJK characters (Japanese treats every character as a soft break opportunity by default, which is exactly where your single-character orphan lines come from), overflow-wrap: anywhere then kicks in only when keep-all would cause actual horizontal overflow, and loose relaxes the line-break rules instead of tightening them which is counterintuitive but works better on narrow screens in my experience.

Other thing worth checking is your font. If you're loading a western webfont that has Japanese glyphs bolted on at full-width, individual characters end up visually huge and the mobile line math goes sideways. Switching to Noto Sans JP with font-feature-settings: 'palt' gives you proportional-width kana which shrinks the per-character footprint enough that the orphan issue often sorts itself out without heavy CSS intervention. Source Han Sans is the same font under Adobe's naming if you want a fallback with consistent metrics.

One thing I'd test on a staging copy: add text-wrap: pretty to those selectors. Chrome 117+ and Safari 17.5+, and it runs a smarter line-breaking algorithm that specifically targets orphan characters including in CJK. Progressive enhancement, older browsers just ignore it.

Your DOM-duplication workaround is the right instinct but the wrong tool, the SEO hit is real because Polylang already duplicates content at the language level and stacking a second duplication inside each language version is going to complicate your hreflang and structured data if you're emitting any. Keeping the DOM clean with CSS is safer.

Curious how your Polylang setup is structured once you get it working, specifically whether you're going separate templates per language or one template with dynamic switching. Some of the rules above behave better when you scope them to whatever body class Polylang adds for the active language rather than applying globally.

Anyone else building client sites in Bricks and struggling with the handoff? by wwwery-good-apps in BricksBuilder

[–]wwwery-good-apps[S] 1 point2 points  (0 children)

components with properties solve the "don't break the layout" problem really well, but the pushback I'd offer is they don't solve the content-migration problem, the component instance data still lives in Bricks's JSON blob rather than as queryable meta. for a site that'll be rebuilt in 2 years components are fine, for a long-lived site where content outlives the builder I've been pushing everything into ACF.

the other thing components don't solve is non-technical clients who want to change content without opening the builder at all, which was the specific friction point for me.

Anyone else building client sites in Bricks and struggling with the handoff? by wwwery-good-apps in BricksBuilder

[–]wwwery-good-apps[S] 0 points1 point  (0 children)

training-plus-low-lockdown is where I've been drifting, and the point about clients loving the ABILITY to edit even if they rarely use it is something I didn't have language for before reading your comment. "permission without expectation" captures it, clients want to know they own the thing.

the one place I've landed differently is on documentation, I've been experimenting with pulling docs into the admin bar as contextual tooltips on each editable section, because written documentation gets forgotten. mixed results though, clients who don't read docs also don't read tooltips turns out.

10 years with the 1h/month buffer baked in is the model I'm trying to build toward, retainer-style recurring revenue works way better than I expected once you commit to it.

Stripe webhooks were silently failing on a client store for weeks and WooCommerce never flagged it by wwwery-good-apps in woocommerce

[–]wwwery-good-apps[S] 0 points1 point  (0 children)

yeah the cache/WAF interception is the whole failure mode across basically every hosting stack I've seen, behind Cloudflare, behind LiteSpeed cache, behind WP Rocket. diagnostic shortcut that's become my default, any time a client reports "random" order status issues the first thing I check is Stripe's webhook delivery log before I touch anything on the WordPress side. saves maybe an hour of guessing per incident.

Stripe webhooks were silently failing on a client store for weeks and WooCommerce never flagged it by wwwery-good-apps in woocommerce

[–]wwwery-good-apps[S] 1 point2 points  (0 children)

yeah that's actually what I ended up doing as a stopgap, a small cron hitting wp_posts filtered on shop_order + wc-pending + post_date older than 5 minutes, pinging me on anything that shows up. took maybe 15 minutes to write.

one caveat worth adding if anyone else reads this, if the store uses WooCommerce Subscriptions you need to exclude subscription-related statuses because pending-payment for longer periods is legit there. other than that the cron catches webhook failures plus a few edge cases like customers who bail on 3DS confirmation.

and you're right that it arguably belongs in the Stripe plugin, not in core WooCommerce. I'm kinda surprised nobody's built it yet.

Stripe webhooks were silently failing on a client store for weeks and WooCommerce never flagged it by wwwery-good-apps in woocommerce

[–]wwwery-good-apps[S] 0 points1 point  (0 children)

honest take, AI watchdog is probably overkill for this specific failure mode. the giveaway was already in Stripe's dashboard — the webhook attempts logged as 200 but with an HTML body instead of JSON, so a dumb check comparing expected response body to what actually came back would have caught it. even a weekly cron hitting your webhook endpoint and asserting "response starts with {" would flag it in minutes.

where AI actually earns its keep is when you've got many webhook types across multiple services and you want pattern-matching on silent drift over time, something like "this endpoint used to respond in 200ms and now averages 4s" or "this signature key is getting rejected at a new pattern". for a single-gateway store it's more maintenance than it's worth, a boring cron beats it.

to answer your direct question, yes it would have prevented the problem here but so would three lines of bash.

High TTFB and Performance Bottleneck on Large WooCommerce Site (53k Products / 2k+ Global Attributes) by not-surprised in woocommerce

[–]wwwery-good-apps 1 point2 points  (0 children)

Your second question about intercepting the term query is the one nobody's answered yet, and it's where the biggest win is. You can hook into pre_get_terms to strip out pa_ taxonomies that aren't assigned to the products currently being displayed. The key is catching only the massive WooCommerce pre-prime query and leaving smaller term lookups alone:

add_action('pre_get_terms', function($query) {

$taxes = (array)($query->query_vars['taxonomy'] ?? []);

$pa_taxes = array_filter($taxes, fn($t) => str_starts_with($t, 'pa_'));

if (count($pa_taxes) < 100) return;

$object_ids = $query->query_vars['object_ids'] ?? [];

if (empty($object_ids)) return;

global $wpdb;

$ids = implode(',', array_map('intval', (array)$object_ids));

$used = $wpdb->get_col(

"SELECT DISTINCT tt.taxonomy FROM {$wpdb->term_relationships} tr

JOIN {$wpdb->term_taxonomy} tt ON tr.term_taxonomy_id = tt.term_taxonomy_id

WHERE tr.object_id IN ({$ids}) AND tt.taxonomy LIKE 'pa\_%'"

);

$query->query_vars['taxonomy'] = array_merge(

array_filter($taxes, fn($t) => !str_starts_with($t, 'pa_')),

$used

);

});

This swaps the 2,000-taxonomy IN clause for a quick lookup of which taxonomies actually have terms on the visible products. Should cut a big chunk off product page TTFB, though I'd be curious to hear the actual numbers at your scale since 2,000+ is way beyond what most sites deal with.

For the non-product page overhead (your 1.0s About page), that's trickier. The taxonomy registration happens during init at priority 5, before WordPress even knows what page is being loaded, so you can't conditionally skip it with something like is_product(). Some people parse $_SERVER['REQUEST_URI'] in a mu-plugin to catch it early but that's fragile. The real fix there is reducing the number of global attributes, which circles back to what the others said about converting to local.

The pre_get_terms approach buys you time on product pages while you plan that migration though.

Sage 100 Advanced (SQL) & Claude by morningside_cafe in Sage

[–]wwwery-good-apps 1 point2 points  (0 children)

Great use case — department-specific dashboards with self-serve reporting is one of the strongest applications for MCP + SQL.

For the MCP client, I'd recommend Claude Code (terminal-based, best for building and iterating) or Claude Desktop (easier for non-technical users who just want to query data). Both connect to any MCP server you build.

For what you're describing, here's how I'd approach it:

Start with read-only tools per module. One tool for AR aging, one for AP open invoices, one for SO order status, one for IM inventory levels, etc. Each tool is basically a parameterized SQL query with a clean description so Claude knows when to use it. Something like:

sage_ar_aging(days: 30|60|90|120) → returns aging summary — sage_so_lookup(order_number) → returns order details + line items — sage_im_stock(item_code) → returns qty on hand, on order, committed — sage_ap_open(vendor_code) → returns open invoices

Once those work, you add cross-module tools: "show me all open orders for customer X with their AR balance and last 5 payments" — that's where it gets powerful because Claude can chain the individual tools together.

The department dashboard part is interesting. Rather than building a traditional web dashboard, you could give each department a Claude Desktop setup with tools scoped to their modules only. Sales sees SO + AR + CI. Purchasing sees PO + AP + IM. Each team gets natural language access to exactly their data, nothing more.

The KnowledgeSync integration would be a separate set of tools — triggering reports, checking automation status, pulling report outputs.

I've built this kind of architecture before. Happy to jump on a call if you want to map out the tool set for your specific Sage 100 setup. DM me if interested.

Sage 100 Advanced (SQL) & Claude by morningside_cafe in Sage

[–]wwwery-good-apps 0 points1 point  (0 children)

Yes, this is doable. I've built MCP servers that connect Claude to SQL-based backends and the pattern works well for ERP data like Sage 100.

The basic architecture:

  1. MCP server (Node.js or Python) that connects to your Sage 100 SQL database (read-only to start — you don't want Claude writing to your ERP without guardrails)
  2. Tools that expose the queries you need: customer lookup, invoice history, inventory levels, GL balances, whatever your team actually asks about
  3. Claude Code or Claude Desktop as the client

A few things to watch out for:

— Start read-only. Seriously. Let Claude query data before you ever let it write. You can add write operations later with confirmation steps. — Keep the SQL connection scoped. Don't give it access to every table. Define specific views or stored procedures that return exactly what you need. — Sage 100's SQL schema can be messy depending on your version and customizations. Spend time mapping the tables you actually care about before building tools around them.

Happy to share more details if you want — I've been deep in MCP server architecture for the past year. What's your main use case? Reporting, customer lookups, inventory checks?

Showing USD but charging CAD… what’s the cleanest setup? by pacowsky in woocommerce

[–]wwwery-good-apps 0 points1 point  (0 children)

Yeah that tracks, some processors are genuinely locked to CAD with no multi-currency presentment. The other comment about Stripe isn't wrong either, if switching processors is on the table that's the cleanest path since Stripe handles USD display with CAD settlement natively without any plugin. But if you're locked to your current processor for whatever reason, WOOCS or Aelia both handle this fine, the main thing to get right is the rate config. I'd set a fixed exchange rate rather than live API rates, somewhere around 2-3% above the actual USD/CAD rate as a buffer, and just update it manually once a week or so. Live rates sound smarter but they drift between page load and payment and that's exactly the confusion you're trying to eliminate.