WP Café #135 | Efficient asset loading 🔗 **Source:** [WP Café #135 | Efficient asset loading](https://www.youtube.com/watch?v=NkfDAyoW5B8) > [!note]+ Document Notes > tags: [wordpress-performance, asset-loading, block-development] > author: WP Café > source: YouTube > reference: https://www.youtube.com/watch?v=NkfDAyoW5B8 > date created: 2024-12-27 10:30 > > # 🏷️ Title: WP Café #135 | Efficient asset loading > <!-- deep-read:sections start --> ## 🧰 Action Inbox - [H1] Split theme CSS into block-specific files — performance optimization #asset-loading - [H2] Test conditional JavaScript loading for block styles — 25:30 timestamp #javascript - [H3] Fix sanitize_title function for special characters — 34:45 timestamp #debugging ## 🧭 Table of Contents - [📝 Summary](#-summary) - [📖 Main Content](#-main-content) - [🗒️ Notes](#️-notes) - [📚 References](#-references) - [🗣️ Paraphrase](#️-paraphrase) - [📰 Newsletter](#-newsletter) - [✅ Action Items](#-action-items) - [🧪 Hypotheses](#-hypotheses) - [📊 Methodology](#-methodology) - [❓ Questions](#-questions) - [🔮 Future Research](#-future-research) - [💡 Implications](#-implications) - [🧠 Learning Styles Assessment](#-learning-styles-assessment) - [📊 Accessibility Assessment](#-accessibility-assessment) - [🌍 DEIB Assessment](#-deib-assessment) - [✅ Logical Validity](#-logical-validity) - [🛡️ DARVO Analysis](#-darvo-analysis) - [🎯 Conclusion](#-conclusion) ### 🔗 References - [WP Café Show](https://wpcafe.show) - [High-Rise Digital](https://high-risedigital.com) ## 📝 Summary - WordPress developers Keith Devon and Mark Wilkinson discuss efficient asset loading techniques for WordPress sites - Core focus on loading block-specific CSS and JavaScript only when blocks are present on pages - Technical solutions include using wp_enqueue_block_style() and render_block filters for conditional loading - Also covers debugging URL encoding issues with special characters and pricing strategy discussions - Bottom line: Performance optimization through conditional asset loading can significantly reduce payload ## 📖 Main Content This episode covers advanced WordPress performance optimization techniques, specifically focusing on conditional asset loading. The hosts demonstrate how to load block-specific CSS and JavaScript files only when those blocks are actually used on a page, rather than loading all assets globally. The technical approach involves using WordPress's built-in `wp_enqueue_block_style()` function combined with file system scanning using PHP's `glob()` function. For JavaScript, they explore using the `render_block` filter to detect specific block styles and conditionally enqueue scripts. They also troubleshoot a real-world issue where special characters (umlauts) in job titles were causing 403 errors, revealing the importance of proper URL sanitization using `sanitize_title()` instead of `sanitize_title_with_dashes()`. ## 🗒️ Notes #### ⏱️ [00:00](https://youtu.be/NkfDAyoW5B8?t=0) — [H1] Introduction and health updates - Key idea: Both hosts dealing with seasonal illnesses affecting UK population - Evidence: "Everyone seems to be a bit down under the weather, don't they?" #### ⏱️ [03:30](https://youtu.be/NkfDAyoW5B8?t=210) — [H2] Performance audit triggers optimization work - Key idea: Large theme CSS file identified as performance bottleneck - Evidence: "One of the main insights was that the theme CSS file was quite large" #### ⏱️ [06:15](https://youtu.be/NkfDAyoW5B8?t=375) — [H1] Block-specific CSS loading approach - Key idea: Using PHP glob() to scan for block CSS files automatically - Evidence: "We get all of the registered blocks and then you kind of loop through each of those" #### ⏱️ [09:45](https://youtu.be/NkfDAyoW5B8?t=585) — [H2] wp_enqueue_block_style() function benefits - Key idea: WordPress handles registration and conditional loading automatically - Evidence: "It registers your CSS file with WordPress and it encues it when that block is detected" #### ⏱️ [12:20](https://youtu.be/NkfDAyoW5B8?t=740) — [H3] CSS inlining for small files - Key idea: WordPress automatically inlines small CSS files for efficiency - Evidence: "It will try and inline those styles if it judges that they are suitable" #### ⏱️ [15:30](https://youtu.be/NkfDAyoW5B8?t=930) — [H2] JavaScript loading for blocks - Key idea: Using block_type_metadata filter for front-end script loading - Evidence: "You can add your script into that. It's called view script" #### ⏱️ [19:15](https://youtu.be/NkfDAyoW5B8?t=1155) — [H1] Conditional JavaScript for block styles - Key idea: Only load JavaScript when specific block styles are applied - Evidence: "I only want to encue that logo slider JavaScript file when that block style is selected" #### ⏱️ [22:45](https://youtu.be/NkfDAyoW5B8?t=1365) — [H3] render_block filter solution - Key idea: Using render_block filter to detect block styles and conditionally enqueue assets - Evidence: "Looking for a class name called is style whatever your style is" #### ⏱️ [25:30](https://youtu.be/NkfDAyoW5B8?t=1530) — [H2] HTTP/2 and multiple requests - Key idea: HTTP/2 handles multiple simultaneous requests efficiently - Evidence: "Browser can only handle one request at a time vs HTTP2 can open a connection" #### ⏱️ [30:15](https://youtu.be/NkfDAyoW5B8?t=1815) — [H2] Editor vs front-end loading considerations - Key idea: JavaScript often shouldn't load in editor due to usability issues - Evidence: "How do you click on an image to then start replacing it if it's a slider?" #### ⏱️ [34:45](https://youtu.be/NkfDAyoW5B8?t=2085) — [H1] Special character URL encoding bug - Key idea: Umlaut characters in job titles causing 403 errors - Evidence: "Job that had the issue had an uml in the title making the URL look very strange" #### ⏱️ [38:20](https://youtu.be/NkfDAyoW5B8?t=2300) — [H3] sanitize_title vs sanitize_title_with_dashes - Key idea: Wrong sanitization function doesn't handle special characters - Evidence: "sanitize_title calls remove_accents which does the replacement" #### ⏱️ [42:15](https://youtu.be/NkfDAyoW5B8?t=2535) — [H2] Pricing strategy and discount philosophy - Key idea: Questioning the logic behind Black Friday sales and discount codes - Evidence: "If you're not selling unless you offer a discount, isn't your pricing just wrong?" #### ⏱️ [48:30](https://youtu.be/NkfDAyoW5B8?t=2910) — [H3] Customer expectations around discounts - Key idea: Discount code boxes create expectation that discounts are available - Evidence: "Is there a Christmas discount that I can use? All feeling of goodwill" ## 📚 References - [WordPress Developer Documentation](https://developer.wordpress.org/) - [WP-CLI](https://wp-cli.org/) - [ACF Blocks Documentation](https://www.advancedcustomfields.com/resources/) ## 🗣️ Paraphrase - WordPress sites can be optimized by loading CSS and JavaScript only when specific blocks are present on pages, rather than loading everything globally - Technical implementation involves scanning theme directories for block-specific asset files and using WordPress's built-in conditional loading functions - Special character handling in URLs requires proper sanitization functions to prevent server errors and ensure cross-browser compatibility ## 📰 Newsletter ## Optimize Your WordPress Performance with Smart Asset Loading This week's WP Café episode dives deep into performance optimization techniques that every WordPress developer should know. The hosts demonstrate practical approaches to conditional asset loading that can significantly improve your site's performance. **Key Technique**: Use `wp_enqueue_block_style()` to automatically load CSS only when specific blocks are present. Combined with PHP's `glob()` function, you can create a system that scans your theme's block assets and loads them conditionally without manual configuration. **Pro Tip**: For JavaScript loading based on block styles, leverage the `render_block` filter to detect specific CSS classes and conditionally enqueue scripts. This prevents unnecessary JavaScript from loading when block variations aren't being used. **Debug Alert**: Watch out for special characters in URLs - use `sanitize_title()` instead of `sanitize_title_with_dashes()` to properly handle international characters and prevent 403 errors. Resources: [Learn WordPress](https://learn.wordpress.org/), [Developer Docs](https://developer.wordpress.org/), [WP-CLI](https://wp-cli.org/) ## ✅ Action Items #### WordPress - Core Performance: Implement conditional asset loading patterns in themes - Themes: Review asset loading strategies for better performance scores - Documentation: Document wp_enqueue_block_style() usage patterns and benefits - Community: Share performance optimization techniques at meetups #### The WPCC - Programs: Developer workshops on performance optimization techniques - Projects: Performance audit tools and guidelines for theme developers ## 🧪 Hypotheses - Conditional asset loading reduces initial page load times compared to bundled assets - HTTP/2 makes multiple small requests more efficient than single large bundles - Block-specific CSS files improve caching strategies for WordPress sites - Special character handling affects international WordPress site reliability ### 📊 Methodology - Performance testing comparing bundled vs conditional asset loading - HTTP/2 request analysis using browser network tools - International character URL testing across different server configurations ### ❓ Questions - How does the number of conditional requests impact HTTP/2 performance? - What's the optimal file size threshold for CSS inlining vs separate files? - How do CDNs handle numerous small asset files compared to bundles? ### 🔮 Future Research - Performance impact studies of conditional loading at scale - Browser caching behavior with block-specific assets - Server configuration optimization for numerous small requests ### 💡 Implications - Practice: Theme developers need to reconsider asset bundling strategies - Performance: Conditional loading can significantly improve Core Web Vitals scores - Education: Developer training should include modern asset loading techniques - Tooling: Build processes need updating to support block-specific compilation ### 🧠 Learning Styles Assessment Reading level estimate: 12th Grade (technical content with code examples) #### 👀 Visual learners - Present: Code examples and file structure explanations - Improve: Network waterfall diagrams, file organization visuals #### 🔊 Aural learners - Present: Podcast format with detailed verbal explanations - Improve: Audio descriptions of code functionality #### 🗣️ Verbal learners - Present: Technical terms explained with analogies and examples - Improve: Glossary of WordPress performance terms #### 🧩 Kinesthetic learners - Present: Step-by-step implementation guidance - Improve: Hands-on code examples and testing procedures #### 🧠 Logical learners - Present: Performance metrics and before/after comparisons - Improve: Decision trees for choosing asset loading strategies #### 🧑‍🤝‍🧑 Social learners - Present: Discussion between hosts, community interaction - Improve: Code review examples, collaborative optimization #### 🧘‍♀️ Solitary learners - Present: Detailed technical explanations for independent study - Improve: Self-assessment checklists for implementation #### 🌿 Naturalistic learners - Present: Performance optimization as ecosystem health - Improve: Environmental impact of efficient loading ### 📊 Accessibility Assessment #### Screen reader semantics - Present: Clear heading structure, code explanations - Improve: More descriptive alt text for code examples #### Keyboard navigation - Present: Standard video controls accessible - Improve: Timestamped navigation for topics #### Contrast and readability - Present: Good contrast in video presentation - Improve: Code syntax highlighting for better readability #### Media and captions - Present: Full transcript provided - Improve: Synchronized captions with technical terms ### 🌍 DEIB Assessment #### Cultural breadth - Present: UK-based perspective with international considerations - Improve: Examples from diverse WordPress communities globally #### Inclusive language - Present: Technical terms explained clearly - Improve: Avoid assumptions about prior knowledge levels #### Representation - Present: Technical discussion focused on practical implementation - Improve: Diverse use cases and examples ### ✅ Logical Validity #### Strong reasoning - Deductive strength: Performance optimization principles well-established - Inductive strength: Real-world examples support general principles - Causal reasoning: Clear connection between asset loading and performance #### Fallacies - None identified: Technical discussion stays factual and evidence-based #### Tone of voice - Overall tone: Conversational and educational, appropriate for developer audience ### 🛡️ DARVO Analysis - No concerning patterns identified - technical discussion focused on problem-solving ## 🎯 Conclusion This episode provides valuable insights into modern WordPress performance optimization through conditional asset loading. The practical techniques demonstrated - using `wp_enqueue_block_style()` for CSS and `render_block` filters for JavaScript - offer immediate improvements for WordPress developers. Key takeaway: Moving beyond traditional asset bundling to conditional loading aligns with modern web performance best practices, especially when combined with HTTP/2's capabilities for handling multiple simultaneous requests efficiently. The debugging insights around URL sanitization also highlight the importance of proper internationalization practices in WordPress development. ## 🧱 Refactor Appendix ### 📚 Literature Split Pad ### [H1] Conditional asset loading improves WordPress performance > [!quote] [WP Café #135](https://youtu.be/NkfDAyoW5B8) by WP Café via YouTube. Published 2024. Accessed 2024-12-27. > "Load block styles only when those blocks are on the page if possible." Performance optimization through selective resource loading. [view highlight](https://youtu.be/NkfDAyoW5B8?t=375#H1) #performance #optimization ID:rw_001 ### [H2] wp_enqueue_block_style handles registration and conditional loading > [!quote] [WP Café #135](https://youtu.be/NkfDAyoW5B8) > "It registers your CSS file with WordPress and it encues it when that block is detected." WordPress provides built-in conditional asset loading functionality. [view highlight](https://youtu.be/NkfDAyoW5B8?t=585#H2) #wordpress-functions ID:rw_002 --- ### 🔖 Atomic Split Pad (Zettel Candidates) #### [Z1] HTTP/2 enables efficient multiple request handling - Modern protocol supports simultaneous asset loading - Pointer to 25:30 timestamp discussion - Links: [[Web-Performance]] [[Asset-Loading]] #### [Z2] Special character sanitization prevents URL errors - Use sanitize_title() over sanitize_title_with_dashes() - Pointer to 34:45 debugging discussion - Links: [[WordPress-Internationalization]] [[URL-Handling]] --- ### ✏️ Fleeting Queue - [F1] Test block-specific asset loading implementation — performance audit context #fleeting #performance - [F2] Review special character handling in current projects — 403 error prevention #fleeting #debugging - [F3] Research optimal file size thresholds for CSS inlining — efficiency optimization #fleeting #research --- ## Full Transcript [00:02] Hello and welcome to episode number 135<br>[00:06] of WP Cafe, the show where we share the<br>[00:08] real unfiltered experience of running a<br>[00:11] WordPress business. I'm Keith Devon and<br>[00:14] as always I'm joined by my co-host Mark<br>[00:16] Wilkinson. We're both from High-Rise<br>[00:18] Digital, which is a tiny agency building<br>[00:20] WordPress websites and products. Today<br>[00:23] we're going to be talking about a number<br>[00:24] of things. I guess mostly about<br>[00:27] efficient asset loading in our WordPress<br>[00:29] websites that we build. Uh so grab a<br>[00:32] brew, settle in as we explore what it's<br>[00:34] really like behind the scenes. You can<br>[00:36] follow us over on X, formerly Twitter at<br>[00:39] WP Cafe Show, and find us on Blue Sky<br>[00:42] and the web at wpcafe.show.<br>[00:46] If you enjoy the episode, hit subscribe<br>[00:48] and like, leave us a comment, and share<br>[00:50] it with someone who might find it<br>[00:51] useful. And we'd love to hear your<br>[00:53] thoughts. So, if you're watching along<br>[00:55] live on YouTube, please do join the<br>[00:56] conversation and let us know what you<br>[00:59] think. So, on to the show. But before we<br>[01:01] get stuck into the topics, let's catch<br>[01:03] up with Mark. Mark, how have you been<br>[01:05] this week? What's been going on?<br>[01:07] >> Uh, not so bad. I'm not uh feeling 100%<br>[01:11] I must admit like the rest of the UK. I<br>[01:14] think everyone seems to be a bit uh down<br>[01:16] under the weather, don't they? So, um if<br>[01:18] I disappear, it's probably because I'm<br>[01:20] about to sneeze my head off. Um but I<br>[01:22] will be back. But when I finish doing<br>[01:24] that, so put your head back on.<br>[01:26] >> Yeah.<br>[01:28] >> So, uh, but yeah, other than that, um,<br>[01:30] doing all right. Just plotting along.<br>[01:32] Uh, yeah. Got a few things to chat<br>[01:33] through today, so it's good. What about<br>[01:34] you?<br>[01:35] >> Yeah. Uh, similar. Took a couple of days<br>[01:38] off at the start of this week. Um, with<br>[01:40] a bit of a a nasty cold. They hit me<br>[01:43] really hard and then disappeared really<br>[01:44] quickly, which is unusual for me because<br>[01:46] usually usually once I get a cold, I'm<br>[01:48] like I'm in it for quite a while. I'm<br>[01:50] still a little bit kind of blocked up,<br>[01:52] but I feel so much better. Um, ginger<br>[01:55] and cinnamon is what I was taking. And I<br>[01:57] don't know. I don't know. It's uh it's a<br>[02:00] sample of one, but uh I I heard I I saw<br>[02:04] some stupid thing on the internet about<br>[02:05] like traditional remedies for colds and<br>[02:08] the guy was all about about it. So, I<br>[02:10] was like, well, I've got I've got ginger<br>[02:11] and cinnamon in the house, so I'll give<br>[02:12] it a go. Few cups of that was right. Um<br>[02:16] but<br>[02:17] >> put it in boiling water, you know.<br>[02:19] >> Yeah. Yeah. Yeah. Yeah. Yeah. I just<br>[02:20] chopped up a bunch of ginger, sprinkled<br>[02:23] in some ground cinnamon with<br>[02:25] >> honey.<br>[02:26] >> Yeah.<br>[02:27] >> Yeah.<br>[02:27] >> Yeah.<br>[02:28] >> And uh Yeah. It was reasonably tasty.<br>[02:31] It's quite fiery and apparently<br>[02:33] apparently that's what works, but you<br>[02:35] know, it gets the blood flowing and blah<br>[02:37] blah blah. Anyway, it's probably<br>[02:39] absolute nonsense, but<br>[02:40] >> um but now my daughter's really sick and<br>[02:42] I've I've got a horrible feeling that a<br>[02:45] hospital visit is imminent cuz she's got<br>[02:47] a very high temperature and I know what<br>[02:50] the GP is going to say. They're just<br>[02:52] going to send us all off to hospital<br>[02:54] with the rest of the country. Like you<br>[02:55] said, like everyone's everyone's sick at<br>[02:57] the minute. So, it could be in for a<br>[02:58] pretty grim 24 hours, but<br>[03:00] >> uh let's enjoy the last of it before<br>[03:02] that happens.<br>[03:06] All right. So, yeah, let's get on with<br>[03:08] uh let's get on with the show. Um, so<br>[03:11] yeah, a few things to chat about there.<br>[03:14] Um,<br>[03:17] the first one is all about basically<br>[03:19] efficiently loading CSS and JavaScript<br>[03:23] in our WordPress sites. And it came<br>[03:26] about I'll do the intro mark because I<br>[03:27] reckon you're going to be talking<br>[03:28] through the technicalities because it's<br>[03:30] mostly been your work so far. Um but it<br>[03:33] came about because of a performance kind<br>[03:35] of audit uh that we're doing for a<br>[03:37] client of ours and one of the you know<br>[03:42] we're just running it through Google<br>[03:43] page speed. One of the main insights was<br>[03:46] that the theme CSS file was quite large<br>[03:49] and it was it's kind of grown over time.<br>[03:52] Um, and it's reasonably big. And we have<br>[03:57] previously and since this project uh<br>[04:02] been much clever about how we kind of<br>[04:04] load our CSS. I don't know how why this<br>[04:06] project kind of we haven't we weren't<br>[04:08] doing those things. Um, but what we what<br>[04:11] we thought is that we should probably be<br>[04:12] loading block styles uh like block CSS<br>[04:16] specifically uh only when those blocks<br>[04:19] are on the page if possible. and we we<br>[04:22] know it is possible. Um so you set about<br>[04:26] to figure out um how to look for<br>[04:31] those assets in a particular place in<br>[04:33] the theme if the block was on the page<br>[04:37] over to you. What challenges did you<br>[04:39] face? What solutions did you come up<br>[04:41] with?<br>[04:41] >> I'm just checking out the right branch<br>[04:43] so I can see my code at the same time as<br>[04:46] >> Yeah, good idea.<br>[04:48] And it magically appears in my file.<br>[04:50] There we go. Um, so I've done this<br>[04:52] before actually, so it's just a matter<br>[04:53] of like revisiting it. And I've actually<br>[04:55] approached it in a few different ways.<br>[04:58] The very first way I approached it was<br>[04:59] to get all of the blocks on the website.<br>[05:02] So you can do that. I think there's like<br>[05:04] a block registry<br>[05:06] class thing and you can get all of the<br>[05:08] registered blocks and then you kind of<br>[05:10] loop through each of those. You check<br>[05:12] whether you've got a file present and if<br>[05:15] you have, you kind of incue it. But that<br>[05:18] that's kind of inefficient. So I thought<br>[05:20] we may as well do it the other way<br>[05:21] around in that if we have a block file<br>[05:23] block file present then loop through<br>[05:27] those and then work out what the block<br>[05:29] is that you need to sort of add the<br>[05:30] block style. So that's the approach I've<br>[05:31] gone for. So essentially we get um we're<br>[05:35] just using the PHP glob function which<br>[05:37] basically looks at a directory of the<br>[05:39] files. So, I'm looking at in this<br>[05:41] directory. I think it's assets. This is<br>[05:43] in the theme. It's assets blocks<br>[05:46] essentially. Um, and it looks for any<br>[05:49] files in there that are ending in CSS.<br>[05:52] And then we loop through each of those<br>[05:54] files. We build a path because you need<br>[05:56] the path. Come to that in a minute. We<br>[05:58] build a file name. And then we from the<br>[06:00] file name, we build the block name<br>[06:01] because obviously the file name is going<br>[06:02] to be like core- paragraph whereas the<br>[06:04] blocks called core slash paragraph.<br>[06:08] bit annoying, but that's what you have<br>[06:09] to do. Um, and then for each of those,<br>[06:12] we then use the core WordPress function<br>[06:15] WP NQB block style,<br>[06:18] >> which kind of does what it says on the<br>[06:20] tin. It it registers your CSS file with<br>[06:23] WordPress and it encues it when that<br>[06:26] block is detected in a page load. So,<br>[06:29] you'll only ever get that loaded if you<br>[06:32] have that block on the page, which seems<br>[06:34] much more efficient. you know, if we've<br>[06:36] got some specific styles for a media and<br>[06:38] text block, but that's not on the<br>[06:39] current page, it seems silly to load the<br>[06:41] CSS for that when we don't need it. So,<br>[06:43] this is trying to attack this so that<br>[06:46] only the CSS you want is loaded.<br>[06:50] And that should help because our CSS<br>[06:52] files quite large. So, we can split that<br>[06:53] into smaller files and only load those<br>[06:55] when they're needed. It makes sense. The<br>[06:58] other thing that the WPMPQ block style<br>[07:02] does and this is why you need the path<br>[07:04] of your stylesheet. Uh it's like the<br>[07:07] path on the server is because it will<br>[07:10] try and inline those styles if it judges<br>[07:13] that they are suitable for being<br>[07:15] inlined.<br>[07:16] >> Um I haven't actually looked into what<br>[07:18] the criteria is that. I think part of it<br>[07:19] is how how much CSS there is in your<br>[07:22] file. So if you've only got a few rules,<br>[07:23] it's probably just going to inline them<br>[07:24] straight away, which is again a little<br>[07:26] bit more efficient. So uh that works. So<br>[07:29] basically once that has that function<br>[07:31] has been running and I've just added<br>[07:32] that into the theme, um it's hooked into<br>[07:36] the ad, uh the in it hook and it will it<br>[07:38] will try and cue styles for each block<br>[07:41] uh if they're present. So now all Keith<br>[07:43] has to do is put the files in the folder<br>[07:46] and they'll just automatically get<br>[07:47] incued because they because of their<br>[07:49] presence essentially when those blocks<br>[07:51] from the page.<br>[07:52] >> So the next task after that is to go and<br>[07:56] look at the theme stylesheet which is<br>[07:57] all one and then try and split that into<br>[08:00] the different block stylesheets and try<br>[08:02] and then<br>[08:04] >> split those out. We'll still have a<br>[08:05] theme stylesheet because not<br>[08:07] everything's rel, you know, relative to<br>[08:08] a block. But, um, that's that's the<br>[08:11] plan. So, I don't know how you're going<br>[08:12] to do that obviously because you're<br>[08:14] using SAS. SAS, is that right?<br>[08:16] >> Yeah. Yeah. CSS. Yeah. Yeah.<br>[08:18] >> So, to try and compile those into the<br>[08:21] right place. I'm not sure. But that's<br>[08:23] the next task. Um, that is the next<br>[08:25] task. We So, Mark, we did something<br>[08:28] similar uh on the Kimolton school. I<br>[08:31] don't want to put you on the spot having<br>[08:32] to remember exactly what code you wrote<br>[08:34] for that.<br>[08:35] >> Yep.<br>[08:35] >> Uh I wasn't compiling my CSS. I was just<br>[08:38] writing CSS files on that particular<br>[08:40] project. I just thought I'd try that as<br>[08:41] an approach. So So my side of things was<br>[08:43] in a way much simpler.<br>[08:45] >> Is is your new approach different to<br>[08:48] what we did for Kim Bolton?<br>[08:50] >> And if so, how and kind of is it better?<br>[08:55] >> Uh no, it's extremely similar. The only<br>[08:57] thing that I have changed, and this is<br>[09:00] because you don't need it with the<br>[09:02] original site where we did this, uh, I'm<br>[09:06] doing the same approach, looping through<br>[09:07] each of the files that we've got.<br>[09:10] >> Yeah. And what I was doing is<br>[09:12] registering a style and then encuing the<br>[09:15] block style which actually you don't<br>[09:17] need to do because the WPNQ block style<br>[09:20] function handles the registration and<br>[09:23] the NQing very much like the WPNQ style<br>[09:26] function does.<br>[09:28] >> If it hasn't been registered, it will<br>[09:29] register it. If it is registered and it<br>[09:31] it won't register it.<br>[09:33] >> So that's the only change here just to<br>[09:34] make it a little bit more efficient. Um,<br>[09:36] but it's essentially very similar.<br>[09:38] >> And are we doing the same thing with our<br>[09:42] JavaScript?<br>[09:45] >> Good. I'm glad you asked. So,<br>[09:48] um, we're not, but we probably could be.<br>[09:53] I've been experimenting with that, uh,<br>[09:56] this week.<br>[09:57] >> Yeah. What what was a key thing for me<br>[10:00] was<br>[10:02] I you can load JavaScript for any block<br>[10:06] on the front end quite straightforward.<br>[10:08] So we've we've done this for this<br>[10:10] particular project. So we have<br>[10:12] >> um I'll take an example. We have a a<br>[10:16] gallery block and we turn that into a<br>[10:19] slider when they want like a logo<br>[10:20] slider. So what we essentially do is we<br>[10:22] create a block style that's called logo<br>[10:26] slider I think it's called and when they<br>[10:28] apply that block style the JavaScript<br>[10:31] that we've got will obviously then hook<br>[10:33] into the CSS class that's added and turn<br>[10:35] it into a slider. So you want to incue<br>[10:38] your JavaScript when the gallery block<br>[10:41] is loaded.<br>[10:42] >> Yes. So you can do that uh using the<br>[10:45] filter called block type metadata which<br>[10:48] essentially filters the block JSON file<br>[10:50] for the blocks in question<br>[10:53] >> and you can add your script uh into<br>[10:56] that. It's called view script. View<br>[10:58] means like viewing is on the front end.<br>[11:00] It's basically load this script when<br>[11:02] we're viewing this on the front end. So<br>[11:03] you'd register a script as you normally<br>[11:05] would and then you'd filter this and<br>[11:07] pass the handle of the script to this to<br>[11:10] this block JSON or this block meta<br>[11:12] filter.<br>[11:13] and then your JavaScript will get loaded<br>[11:15] when the block's on the front end.<br>[11:17] >> Okay,<br>[11:17] >> now that's great and it works for any<br>[11:19] block as long as it has a block JSON<br>[11:21] file because that's what you're<br>[11:22] filtering. So if you've got a very old<br>[11:24] ACF block that was using like ACF<br>[11:26] register block type, it didn't work for<br>[11:28] that. So we and we've got a few blocks<br>[11:30] like that. So we need to update them<br>[11:31] slightly.<br>[11:32] >> Um but they have other functions that<br>[11:34] you can use to to encue assets as well.<br>[11:36] So you can still do this, it's just a<br>[11:38] different method. Um, the one thing it<br>[11:40] doesn't do, which is what I really<br>[11:42] wanted to try and solve, is that I only<br>[11:45] want to encue that um, logo slider<br>[11:50] JavaScript file that you've written when<br>[11:52] that block style is selected. I don't<br>[11:54] want to incue it. If they just had a<br>[11:56] gallery, a normal gallery, there's no<br>[11:58] point. It's a waste. They don't need it.<br>[11:59] >> Yeah. So, that's what we have been doing<br>[12:01] currently. So we we've got scripts for<br>[12:02] example that get loaded on every<br>[12:04] paragraph block because there's a<br>[12:05] certain paragraph style that<br>[12:07] >> correct<br>[12:07] >> does like a little counter. Yeah,<br>[12:09] >> correct that does a little counter. So<br>[12:10] every every paragraph has that which<br>[12:12] essentially means it runs on every page<br>[12:14] because pretty much every page has a<br>[12:16] paragraph. So I went about trying to<br>[12:19] solve that issue of how do we how do we<br>[12:22] only incue uh block assets sorry block<br>[12:26] uh JavaScript when the block is actually<br>[12:29] being viewed. And I'm actually just<br>[12:30] going to load up the post I wrote. Uh,<br>[12:34] hang on. So I can actually get the code<br>[12:35] in front of me. Um, and then we can see.<br>[12:40] So I I asked used a bit of um AI as we<br>[12:44] do and uh got some help from from Bob.<br>[12:48] But essentially what I wanted to do is<br>[12:50] to say<br>[12:52] if this block has this block style then<br>[12:56] I want to somehow incue our JavaScript.<br>[12:59] So we'll use the logo slider as an<br>[13:01] example.<br>[13:03] So and the way in which I'm doing that<br>[13:05] is you you can't you can't do that with<br>[13:10] filtering the block metadata because at<br>[13:13] that point in time the instance of the<br>[13:16] block hasn't loaded. You're just sort of<br>[13:18] saying this is the data for all blocks<br>[13:21] if you know what I mean.<br>[13:22] >> Yeah.<br>[13:23] >> Not the actual instance that's on your<br>[13:25] page.<br>[13:26] >> Yeah.<br>[13:26] >> So the the only method that I found to<br>[13:28] do it with you have to do that using the<br>[13:30] render block filter which if you didn't<br>[13:33] know the render block filter allows you<br>[13:36] to change the block HTML and it also<br>[13:40] allows you to to obviously run your own<br>[13:42] code at the same time.<br>[13:43] >> Yeah. So there is also render block<br>[13:46] filters for each individual block. So<br>[13:48] render_block underscore and then the<br>[13:50] block name will only run your code on<br>[13:53] that particular block. So in the gallery<br>[13:55] one we do render block core slash<br>[13:58] gallery and then we'd run our code. And<br>[14:00] what we're doing with in the code that<br>[14:02] I've got is it's looking for a class<br>[14:04] name called is style whatever your style<br>[14:08] is. Ours is logo slider. If that class<br>[14:10] is not present, then we just return the<br>[14:13] normal block content as it was. We don't<br>[14:15] want to touch it. We just finish there.<br>[14:16] That's it. If that is the case, then<br>[14:20] what we can do is run the WPNQ script<br>[14:23] function, which will encue our logo<br>[14:26] slider JavaScript. Um, and then just<br>[14:29] return the block content as it was. We<br>[14:31] don't we don't want to touch the block<br>[14:32] content. We're not really interested in<br>[14:33] that. We just want to do something at<br>[14:34] the point the block loads.<br>[14:35] >> Yeah.<br>[14:36] >> And that works really well. um the the<br>[14:38] and it the the script gets encued only<br>[14:40] when your style is run.<br>[14:43] >> Haven't tested it on the actual site<br>[14:46] yet. I've been running it on a local<br>[14:47] little test environment, just a simple<br>[14:49] test WordPress.<br>[14:50] >> Um but I've added multiple blocks of<br>[14:53] different styles and it all seems to<br>[14:54] only load when you you've obviously got<br>[14:56] your style selected.<br>[14:58] >> Yeah.<br>[14:58] >> Which is great. So we just need to do a<br>[15:00] bit more testing. But yeah, it's good.<br>[15:01] >> Very cool. Um, few comments I think we<br>[15:04] should go through now while we're fresh<br>[15:06] on the topic. First of all, a little<br>[15:09] wave uh from Mark. Uh, Mark,<br>[15:12] >> nice to have you. Nice to have you here,<br>[15:13] Mark. Um, Courtney uh says, "I always<br>[15:16] registered CSS and JS with each ACF<br>[15:20] block in brackets JSON. However, this<br>[15:23] created too many HTTP requests and<br>[15:25] caused its own issue. Um, do you use<br>[15:28] asset bundling?"<br>[15:31] have to say I don't know what asset<br>[15:33] bundling is.<br>[15:34] >> I don't know. No.<br>[15:35] >> Um but yeah, so obviously this will<br>[15:38] create more HTTP requests. Um if we're<br>[15:41] breaking up stylesheets and JavaScript<br>[15:44] files into you know smaller smaller<br>[15:46] chunks um that<br>[15:51] was that HTTP2<br>[15:53] can handle that<br>[15:54] >> and I'll bring in Mark uh for for for<br>[15:57] that. So Mark then comments if the site<br>[15:59] is loaded over HTTP2<br>[16:02] then it's more efficient to load<br>[16:04] separate files than one merged file. If<br>[16:06] the path attribute is passed the WP and<br>[16:10] Q block style then the CSS is inlined<br>[16:14] which makes the issue of separate asset<br>[16:17] loading moot. Okay. So that is what I<br>[16:21] kind of thought as well. I mean, does it<br>[16:23] get to a point where even with HTTP2,<br>[16:27] you know, like you can have too many<br>[16:30] requests? I I don't know because<br>[16:32] presumably it can only kind of handle a<br>[16:33] certain number at a time. Um<br>[16:36] >> I don't I don't know. My my<br>[16:37] understanding with HTTP one or whatever<br>[16:40] it was it 1.1 can't remember.<br>[16:42] >> Was that the browser can only handle one<br>[16:44] request at a time? So, it requests the<br>[16:47] JavaScript file. It waits for the server<br>[16:49] to respond. the server responds with a<br>[16:51] JavaScript file and it requests the next<br>[16:53] one and so on. Whereas with HTTP2,<br>[16:56] I understand was it it can like open a<br>[16:58] connection and then it can say like give<br>[17:00] me this one, this one, this one, this<br>[17:01] one, this one, this one and then it can<br>[17:02] just send them to you.<br>[17:03] >> Yeah, you can see that in the network<br>[17:05] tab on most websites now. So if if you<br>[17:07] open the network tab and you can see<br>[17:09] that kind of waterfall view,<br>[17:10] >> they'll quite often just be like it gets<br>[17:13] to the kind of right, I need to load my<br>[17:14] CSS or JavaScript files now and they're<br>[17:16] all just stacked exactly vertically like<br>[17:19] >> they happen at the same time in instead<br>[17:21] of like one after another. So instead of<br>[17:24] like the step effect that you used to<br>[17:25] get, it's just a single kind of line.<br>[17:27] It's just like bang, they're all done in<br>[17:29] in in one go. Um Elliot then says, hi<br>[17:34] Elliot. He says, "Agree. SAS compilers<br>[17:37] aren't great for blocks work as they<br>[17:40] need to only load if the block is loaded<br>[17:42] on the page." So, yeah, not compiling<br>[17:44] all of your I guess he's saying agreeing<br>[17:46] that not compiling all of our block CSS<br>[17:49] into one uh into one file is is the<br>[17:52] right is the right thing to do. Uh and<br>[17:54] he says, "Just so happens I created a<br>[17:56] PHP class for extending block assets for<br>[17:59] CSS and JS in my GitHub." Go. Uh I think<br>[18:03] we've kind of biged up Elliot before,<br>[18:05] but he puts out a lot of really great uh<br>[18:07] WordPress developer content. So please<br>[18:09] do go and check out his stuff uh<br>[18:11] including his GitHub and his YouTube<br>[18:13] channel. Um and then one more from<br>[18:16] Elliot Hook WP and Qcript 2 and QB block<br>[18:21] assets should work.<br>[18:24] You might have to help me with that one.<br>[18:26] Mark Hook, I'm not quite sure what he<br>[18:29] means there. So, uh, NQ block assets is<br>[18:33] a hook that will run on both the front<br>[18:35] end and the back end.<br>[18:37] >> Mhm.<br>[18:38] >> So, if you want if you want your<br>[18:40] JavaScript to load in the editor as well<br>[18:42] as in on the front end, then you'd want<br>[18:44] to use ENQ block assets<br>[18:47] >> rather than something like render block.<br>[18:49] I would imagine that's what he's<br>[18:50] meaning.<br>[18:51] >> Most of the time with these things, we<br>[18:53] don't want to load these in the in the<br>[18:55] editor because it actually makes editing<br>[18:59] JavaScript.<br>[19:00] >> Yeah, we don't load the JavaScript<br>[19:02] because actually if you turn it into a<br>[19:03] slider in the back end,<br>[19:05] >> how do you click on an image to then<br>[19:07] start replacing it and stuff like that?<br>[19:09] >> It depends what you're doing. I think<br>[19:12] the time, but I find most of the time<br>[19:15] you probably don't want to load the<br>[19:17] JavaScript in the back end, but that is<br>[19:20] very specific to what you're doing.<br>[19:22] Yeah, that's exactly what Courtney's<br>[19:23] asking here. She she said, uh, how do<br>[19:25] you render sliders in the admin? Do you<br>[19:27] write admin CSS to just show one slide<br>[19:30] for example the way we've done it so uh<br>[19:34] there's lots of different ways uh it<br>[19:37] depends on the slider um you know we<br>[19:39] we've built kind of custom blocks with<br>[19:42] uh that are sliders and in that case<br>[19:44] we're often just using ACF to build the<br>[19:46] block and then just using like a<br>[19:48] repeater field so there is really no<br>[19:50] what you see is what you get kind of<br>[19:52] experience<br>[19:53] um<br>[19:55] or we're using a current block like the<br>[19:58] gallery block for example. And in the<br>[20:00] back end in the editor, we just leave it<br>[20:02] as a gallery so that the client, the<br>[20:06] user, the editor can see all of the<br>[20:08] images uh and just click on them and<br>[20:10] change them and and move them around<br>[20:12] like they would with a normal gallery<br>[20:14] just knowing that on the front end it's<br>[20:16] not going to look like that. that that's<br>[20:18] the compromise that we've found because<br>[20:19] I think having a proper slider interface<br>[20:22] and having to kind of as a gallery would<br>[20:24] be<br>[20:25] >> could be pretty horrible as a as a user<br>[20:27] interface.<br>[20:28] >> This is where the block editor often<br>[20:30] conflicts with this what you see is what<br>[20:32] you get. Like sometimes it just isn't<br>[20:35] easier to to handle what you see is what<br>[20:37] you get in the back end. Like you it<br>[20:39] doesn't make sense. Like with this<br>[20:40] slider, it'd be so difficult to sort of<br>[20:42] like change images because often would<br>[20:44] be off the screen cuz they're on a<br>[20:45] slider.<br>[20:46] >> Yeah. Yeah.<br>[20:46] >> So you'd have to slide everything across<br>[20:48] and then it just doesn't really make<br>[20:50] sense.<br>[20:50] >> And actually<br>[20:52] despite some of its limitations which<br>[20:54] are obviously changing that's one of the<br>[20:57] reasons I actually really like building<br>[20:58] blocks with ACF because you're getting a<br>[21:01] very kind of datacentric editing editor<br>[21:04] view.<br>[21:05] >> Uh and then you can you could switch<br>[21:07] across to the like the preview mode<br>[21:09] which will show what it looks like.<br>[21:11] >> Yeah. And you've got this edit mode<br>[21:13] which is a better sometimes editing<br>[21:16] experience. Um<br>[21:17] >> it is now with the new ACF.<br>[21:19] >> Certain yeah certainly like coming on<br>[21:21] leaps and bounds at the minute. So<br>[21:23] >> two two of the new features of ACF 6.7<br>[21:27] are inline editing. So you can just edit<br>[21:30] things by clicking on them kind of like<br>[21:31] you're doing a block editor. I think<br>[21:33] that only works for a limited number of<br>[21:34] blocks at the moment ACF blocks. Um, and<br>[21:38] then the other one is that you have this<br>[21:39] new sort of like panel that can come out<br>[21:41] on the right hand side rather than fill<br>[21:43] in the block sidebar. So have a look at<br>[21:45] those things. They're quite nice as<br>[21:46] well.<br>[21:47] >> Yeah, it's interesting. So Elliot says<br>[21:50] here,<br>[21:51] take the interactivity API. It's only<br>[21:54] available in the front end. So there is<br>[21:57] no uh Wizzywig<br>[22:00] with the interactivity API. So I wonder<br>[22:02] I haven't really played with<br>[22:03] interactivity API so I don't know kind<br>[22:07] of what that what that then looks like<br>[22:09] in the editor. I don't really even know<br>[22:10] how to kind of how to use it yet. But<br>[22:12] that that is interesting. That's<br>[22:13] something bit of bit of a potential<br>[22:16] limitation there. But I'm sure that's<br>[22:18] something that they'll look at in the<br>[22:19] future. Um<br>[22:20] >> yeah true.<br>[22:21] >> But yeah so so kind of fun stuff. So,<br>[22:23] I've I've not now got to rewrite my npm<br>[22:27] scripts to uh to save my instead of<br>[22:30] compiling all my CSS into one uh theme<br>[22:34] file, I need to get them all saving in<br>[22:37] the right places. So, that's that's my<br>[22:38] little challenge. I don't think that's<br>[22:39] going to be too difficult. Um but<br>[22:41] hopefully I'll have that ready to talk<br>[22:43] about maybe for next week or early in<br>[22:45] the new year.<br>[22:46] >> Um<br>[22:48] >> we we also don't minify it yet, do we?<br>[22:50] As well, which we could do. The saving<br>[22:52] on that wasn't particularly massive<br>[22:53] though, was it?<br>[22:56] >> We should.<br>[22:57] >> We should. We should do it. It wasn't<br>[22:59] groundbreakingly. Oh my god, that's<br>[23:00] harvest time. It was a tiny amount. But<br>[23:04] >> makes sense.<br>[23:05] >> You're automating it anyway with with<br>[23:06] SAS. Makes sense. Just squash it all.<br>[23:09] >> Yeah. Yeah. Yeah. Same same with<br>[23:12] JavaScript. So, yeah, probably probably<br>[23:15] look at that as well. Um, there's one<br>[23:17] more kind of technical one that I just<br>[23:18] want to cover. Just an interesting issue<br>[23:21] that we came across today<br>[23:24] uh which is one of our job relay<br>[23:27] customers um and a and a rack press<br>[23:29] customer actually. So we built their job<br>[23:31] board uh hooked it up to Bullhorn for<br>[23:34] them and I got an email this morning<br>[23:38] saying one of our one of our jobs is<br>[23:40] 403ing and I was like that's kind of<br>[23:42] weird and writing off that one 403ed and<br>[23:44] all the other jobs didn't. Um and I had<br>[23:48] a The thing that just jumped out at me<br>[23:50] almost as soon as I saw it was that the<br>[23:54] the job that had the issue, the 403 um<br>[23:57] had an uml in the uh title of the job.<br>[24:01] Uh and it was making the URL look very<br>[24:04] very strange. Um so we we've kind of dug<br>[24:08] into that a little bit this morning. How<br>[24:11] have we actually kind of found the<br>[24:12] solution or figured it out or or do you<br>[24:15] are we still a bit confused? I haven't<br>[24:17] tested it yet.<br>[24:18] >> Yeah.<br>[24:18] >> But I'll explain what happens. So<br>[24:21] >> yeah,<br>[24:22] >> when a job gets delivered from or gets<br>[24:25] delivered to the website, wherever it's<br>[24:27] coming from, whether it's Bullhorn or<br>[24:29] Broadbean or Logic Melon or whatever it<br>[24:30] is, um we simply use the WP insert post<br>[24:34] function to sort of create the post in<br>[24:36] WordPress, the job post. And obviously<br>[24:40] we pass the uh the job title into there<br>[24:44] when you create the post. And WordPress<br>[24:46] automatically generates the post name if<br>[24:49] you don't specify it. And it'll generate<br>[24:51] it by taking the title and essentially<br>[24:54] separating it with dashes um and doing a<br>[24:56] few other checks and things. One of<br>[24:58] those checks that WordPress does is to<br>[25:00] check for I'm just going to call them<br>[25:02] weird characters.<br>[25:04] I'm I'm sure that uh Germans and French<br>[25:07] don't call them weird, but apologies for<br>[25:08] that.<br>[25:09] >> Special characters.<br>[25:10] >> Special characters. Are they special?<br>[25:12] They're not special to those anyway.<br>[25:14] >> Non-standard<br>[25:16] >> English characters. I don't know what to<br>[25:17] call them, but you<br>[25:18] >> There is an official word for this, but<br>[25:19] we haven't got it. So,<br>[25:21] >> yeah. And what it does is it it strips<br>[25:23] those out. So, for example, in this<br>[25:26] particular case, it was the letter A<br>[25:28] with an over, which if you don't know,<br>[25:29] it's got two little dots over the top of<br>[25:31] it. Um, and it just strips out for a<br>[25:33] normal A and then saves the the post<br>[25:35] name. Um, but then in in my code, what<br>[25:38] we do next is we actually update the<br>[25:41] post name once the post has been created<br>[25:44] with appending the post ID. So I can't<br>[25:47] do it when the post is created because<br>[25:49] at that point I don't know the ID. So I<br>[25:51] append the post ID at the end of it in<br>[25:53] an update. And the reason we do that is<br>[25:54] so every job has a unique URL because<br>[25:57] lots of recruiters they recruit the same<br>[25:59] sort of jobs. So they end up posting a<br>[26:02] job and it's like<br>[26:03] marketing-manager-london<br>[26:06] and then that job gets deleted and<br>[26:08] another one comes in and it has the same<br>[26:09] URL as the original and it just confuses<br>[26:12] ATS systems. It confuses lots of things.<br>[26:15] >> Yeah.<br>[26:16] >> So long short long story short is we put<br>[26:18] the post ID on the end so they're always<br>[26:20] unique. And when I'm doing that update,<br>[26:23] so say WP update post and I'm changing<br>[26:26] the post name, I needed to sanitize the<br>[26:29] title. So, I used sanitize title with<br>[26:33] dashes, which it kind of does what it<br>[26:35] says on the tin. It puts dashes in the<br>[26:36] title that that was given.<br>[26:38] >> However, it would appear that that does<br>[26:41] not convert the accents<br>[26:44] or<br>[26:46] special characters or whatever we're<br>[26:47] calling them. It doesn't do that. It<br>[26:49] doesn't do that at all. So, then it left<br>[26:52] that in the URL and then when you view<br>[26:54] it, again, I'm not entirely sure why it<br>[26:57] 403s. Is that a server thing? Is that a<br>[26:59] I don't know, but it's 403s and it it's<br>[27:01] clearly the problem because you replace<br>[27:02] it and it doesn't. However, what I've<br>[27:05] since worked out I think today is that<br>[27:08] you should use sanitize title and the<br>[27:12] reason for that is because sanitize<br>[27:14] title I believe calls sanitize title<br>[27:18] with dashes and it calls the function<br>[27:22] called remove accents which is does this<br>[27:24] little replacement between the special<br>[27:26] characters to normal ones. So, I need to<br>[27:29] update our plugin to swap that sort of<br>[27:31] sanitization function out. And I think,<br>[27:34] as I said, I haven't tested it, but once<br>[27:35] I do that, it will actually solve this<br>[27:37] problem.<br>[27:39] >> Yeah, we'll see.<br>[27:40] >> It's a weird one. I can't believe we<br>[27:41] haven't come across it before.<br>[27:43] >> Yeah, that's what I was I was amazed<br>[27:45] that this hasn't been a problem before.<br>[27:46] So,<br>[27:47] >> and you're thinking maybe that is<br>[27:48] because there's some kind of like server<br>[27:50] level configuration or even something<br>[27:51] within WordPress that's kind of<br>[27:55] >> like a security plugin or something that<br>[27:56] isn't isn't loving the the character but<br>[27:59] >> yeah basically trying to again I'm<br>[28:02] completely making this up as a guess but<br>[28:04] if the server is seeing that in the URL<br>[28:07] is it sort of some firewall saying that<br>[28:10] looks a bit weird I'm just going to<br>[28:11] block it 403 access denied unauthorized<br>[28:13] whatever I don't know. Yeah.<br>[28:16] >> Yeah. So Marcus said make sure that the<br>[28:19] saved value part of the post name has<br>[28:21] been run through sanitized title.<br>[28:24] That will convert characters.<br>[28:26] >> Exactly.<br>[28:27] >> And most browsers understand special<br>[28:29] characters, but if they're not converted<br>[28:31] properly, eg UTF8,<br>[28:34] uh then that may well cause a problem.<br>[28:37] So yeah, that's I think that's what<br>[28:39] we've been uh experiencing. So yeah,<br>[28:41] hopefully we'll get a fix out for that.<br>[28:43] But<br>[28:44] >> essentially, it's me using the wrong<br>[28:46] function.<br>[28:47] >> But like<br>[28:48] >> my brain thought sanitiz title with<br>[28:50] dashes was the right function because<br>[28:52] that's literally what I want to do. I<br>[28:53] want to take the tile and put the dashes<br>[28:54] in the right place. So it's not you know<br>[28:56] what I mean? But apparently no. You<br>[28:58] should use sanitize title.<br>[29:00] >> You learn something every day.<br>[29:01] >> Yeah. Yeah. Yeah. Yeah. It's that was<br>[29:03] interesting. But yeah, hopefully a<br>[29:05] little fix there, a little improvement<br>[29:06] to the product. So that's good. Um, last<br>[29:10] thing on the list and I don't think well<br>[29:11] well maybe we will won't take too long<br>[29:14] on this I don't think um is sale pricing<br>[29:17] and discounts. So sale Why did why did<br>[29:22] you put this one on the list? What was<br>[29:24] uh<br>[29:25] >> well I think I was watching<br>[29:27] >> I was watching WP Builds earlier this<br>[29:29] week and they were sort of chatting<br>[29:30] about Black Friday deals and things like<br>[29:32] that.<br>[29:32] >> Yeah.<br>[29:33] >> Um and then we had a customer actually<br>[29:35] which has kind of brought it up again.<br>[29:37] So I we had a customer earlier this week<br>[29:39] and they were I'd sent them everything<br>[29:40] that they need to buy the product. They<br>[29:42] decided to buy the product and then um<br>[29:46] interestingly on the call they'd already<br>[29:48] said oh I spoke to you three years ago<br>[29:50] and then it was like your product was 35<br>[29:52] quid and you know now it's 49 quid. So<br>[29:56] immediately I'm thinking you know<br>[29:58] they're thinking about discounted prices<br>[30:00] and and I just said well you know the<br>[30:02] world's moved on since then the price is<br>[30:04] what it is now sort of thing. And then<br>[30:07] the customer uh I sent them everything<br>[30:10] they need to buy it. They said, "Yeah,<br>[30:11] yeah, I'm going to go ahead and buy it<br>[30:11] now." And then they sent an email about<br>[30:13] like two minutes later says, "Oh, I can<br>[30:14] see there's a discount code box on your<br>[30:16] checkout page, you know, is there a<br>[30:17] Christmas discount that I can use?" You<br>[30:18] know, you know, all feeling of goodwill<br>[30:20] and stuff. So, I was just thinking and<br>[30:23] it got me thinking about Black Friday<br>[30:24] prices as well, you know, like<br>[30:28] why offer a Black Friday deal? I don't<br>[30:30] quite understand it because why are you<br>[30:33] offering this sale? Because if people<br>[30:36] want the product, then surely they will<br>[30:39] they will pay for it. And if<br>[30:41] >> if you're not selling them unless you<br>[30:45] offer a discount, then isn't your<br>[30:47] pricing just wrong? As in make the price<br>[30:50] the Black Friday discount<br>[30:52] rather than having to run these sales<br>[30:54] and discount codes. I don't understand<br>[30:55] it.<br>[30:56] >> Yeah.<br>[30:56] >> But then we we were talking earlier,<br>[30:58] weren't we about businesses have<br>[31:00] different models, don't they? How they<br>[31:01] sell things. You know, if you think<br>[31:03] about um you know, sofa companies in<br>[31:05] this this country,<br>[31:07] they constantly have offers on. Like you<br>[31:09] you you'd never buy a full price sofa in<br>[31:12] this country because they've literally<br>[31:14] like<br>[31:15] >> they always got a sale on. So<br>[31:17] >> do do a lot of businesses run<br>[31:19] >> which is technically illegal by the way.<br>[31:22] >> I'm pretty sure<br>[31:23] >> I'm I'm sure they're not being illegal<br>[31:25] because they'll be pricing them at the<br>[31:26] right price for certain periods just<br>[31:28] long enough and so on.<br>[31:30] >> Yeah. Yeah. Exactly. Yeah. So is is the<br>[31:33] customer and I'm taking this customer in<br>[31:36] particular for us are they seeing like<br>[31:38] oh it's it's £419 a year is job really<br>[31:41] yeah but we're not going to pay that way<br>[31:42] because there's always going to be some<br>[31:43] sort of like discount that they're going<br>[31:44] to give us on the call you know and that<br>[31:46] sort of thing and a lot lot has that you<br>[31:48] know is that the best price you can do<br>[31:49] and everything like that and I'm like<br>[31:51] yeah because that that's how much it<br>[31:53] costs whereas I think other custo other<br>[31:55] companies might be yeah but if you buy<br>[31:58] it today we can give you a discount code<br>[31:59] for 20% off and and and so on. So, is<br>[32:02] the customer that was asking us in the<br>[32:04] mindset that if they pay £419,<br>[32:08] then they're they're losing out like why<br>[32:10] are they paying that much when there's a<br>[32:11] discount code box on the checkout and<br>[32:13] everyone else will be putting a discount<br>[32:14] code in there and I'm not.<br>[32:16] >> So, it's an interesting<br>[32:18] >> I just think it's a really interesting<br>[32:19] like mindset. My my my thought process<br>[32:24] is that we shouldn't offer discounts. We<br>[32:27] shouldn't offer discounts for for the<br>[32:29] product and because we value well we we<br>[32:33] price the product at what we think is a<br>[32:35] value to the customer and they either<br>[32:38] think that's valuable or not. Now if we<br>[32:40] experience that and like you know 75% of<br>[32:43] the customers book calls they love the<br>[32:45] product and then they I'm not buying it<br>[32:46] because the product is the price is too<br>[32:48] expensive then we'd have to think about<br>[32:50] whether it's the right price.<br>[32:52] >> But I don't think that's the case with<br>[32:53] our product. I think the price is the<br>[32:55] right price.<br>[32:56] So why would we want to offer discounts?<br>[32:58] I don't quite understand why that would<br>[33:01] be the right thing to do.<br>[33:02] >> And it's so I think our product is so<br>[33:04] niche as well that we don't have a lot<br>[33:06] of kind of direct competition. There<br>[33:08] isn't we we actually do have some<br>[33:10] competition in in our in our space for<br>[33:12] job relay, but it's not like<br>[33:15] it's not like buying a a hi-fi or like a<br>[33:19] TV and you're and you're like you could<br>[33:21] buy the same Panasonic TV from a million<br>[33:25] different places and you're going to<br>[33:26] search through all through them all to<br>[33:27] find the one that's giving you the the<br>[33:29] best deal.<br>[33:30] >> Like<br>[33:31] >> yeah, I I I've got kind of different<br>[33:33] experiences, I guess, with sales and<br>[33:35] discounts. So, for example, I just<br>[33:38] bought a soundbar for my home, my my TV<br>[33:42] in my living room.<br>[33:43] >> Uh, and I've I've waited for nearly two<br>[33:47] years actually for a Black Friday sale<br>[33:48] because I forgot to buy it last year.<br>[33:51] Um, so like Black Friday came along and<br>[33:53] I was like, right, I I'm actually going<br>[33:55] to like troll about and see if I can<br>[33:57] find a good sound bar for a good price.<br>[33:59] And I did and I bought it. So having a<br>[34:03] Black Friday sale at this point in time<br>[34:05] meant I bought that particular thing. So<br>[34:08] but<br>[34:08] >> but if they never had a Black Friday<br>[34:10] sale, would you have waited two years to<br>[34:13] get a Black Friday deal or would you<br>[34:15] have decided<br>[34:16] I'm going to buy?<br>[34:17] >> No, cuz I Well, I didn't have a specific<br>[34:21] model in mind until now. So, I just I<br>[34:24] just knew that like electronic equipment<br>[34:27] is<br>[34:29] is sold on Black Friday. It's nearly<br>[34:31] always discounted around this time of<br>[34:32] year, but like do people think of think<br>[34:34] like that with WordPress products and<br>[34:36] plugins and web SAS stuff<br>[34:39] >> as wait for Black Friday.<br>[34:41] >> Yeah. So, there's the Black Friday<br>[34:42] thing. I think Katie Keith has loads of<br>[34:44] like thoughts on this. She's run like<br>[34:46] experiments and put stuff out into the<br>[34:48] world. to maybe like try to track down<br>[34:50] some of her content on whether Black<br>[34:52] Friday works or not. I think it's been a<br>[34:54] bit hit and miss. I think they sell a<br>[34:55] lot because it's discounted. It's not<br>[34:57] quite right. I don't know.<br>[34:59] >> It'll it'll work. I mean, why won't it<br>[35:02] work? Like, you're probably going to<br>[35:04] sell products around Black Friday if<br>[35:06] you've got a Black Friday discount.<br>[35:07] Like, it's not rocket science, is it?<br>[35:08] People are going to anyone who was in<br>[35:10] two minds and like they jump on, oh,<br>[35:12] they've got a black, oh right, okay,<br>[35:13] I'll buy it now. So, I don't I don't<br>[35:15] quite understand like that will work,<br>[35:16] but you're selling it for less than you<br>[35:19] thought it was worth.<br>[35:20] >> Yeah.<br>[35:21] >> And and if if the cases, well, actually,<br>[35:23] Hang on, most customers aren't buying<br>[35:25] it. They're just waiting until Black<br>[35:26] Friday. Why not just make the Black<br>[35:28] Friday price the price?<br>[35:32] >> And then you'll sell them all year.<br>[35:34] >> Yeah.<br>[35:36] Yeah.<br>[35:36] >> Because that's the price we want to pay<br>[35:38] for it.<br>[35:39] >> I really don't I really don't know.<br>[35:41] Yeah. One company that I think jumps<br>[35:44] into mind is is Apple. Like they don't<br>[35:45] do sales.<br>[35:47] >> Yeah.<br>[35:47] >> They just don't do sales. So no one<br>[35:49] feels they're missing out because they<br>[35:51] never do sales. So the price you see on<br>[35:53] the website is the price I pay, you pay,<br>[35:56] everyone pays.<br>[35:57] >> Yeah, that's true.<br>[35:58] >> There's no feeling of missing out or<br>[36:00] anything. The only thing they do is like<br>[36:01] the student thing, don't they? Get like<br>[36:03] a AirPods if you buy something for<br>[36:05] students.<br>[36:06] >> But that's it. That's that's<br>[36:07] >> all. Yeah. Yeah. Yeah. We we have priced<br>[36:10] our MacBook Pro at this price and that's<br>[36:12] it.<br>[36:12] >> I remember when I was going to going to<br>[36:15] buy a car. Uh I think it was maybe the<br>[36:18] first time I'd ever like gone to like a<br>[36:20] dealership to like to buy a car.<br>[36:22] >> And I I'm I'm an introvert. I'm a<br>[36:25] conflict avoider. The thought of like<br>[36:27] haggling on a price is just like<br>[36:29] kryptonite to me. But I thought I'm<br>[36:30] going to I'm going to do it. I'm gonna<br>[36:33] like I'm gonna be brave and I'm gonna<br>[36:34] like so like the salesman sits us down<br>[36:38] and he goes right and this is the price<br>[36:39] and like outlines and everything and I<br>[36:40] was like okay so you know can you you<br>[36:43] know what kind of what kind of deal can<br>[36:45] you do like what's what's the lowest you<br>[36:47] can go he's like no that's that's it I<br>[36:49] was like no seriously come on and he<br>[36:51] just I was I was certain I was in a car<br>[36:55] dealership I was certain there was a<br>[36:57] lower price to be had and it really<br>[37:00] really annoyed me that he just wouldn't<br>[37:02] budge<br>[37:03] And in the end, like<br>[37:04] >> did you walk away?<br>[37:05] >> No, I think I told this story.<br>[37:07] >> She just walked away.<br>[37:10] >> I can't remember if I threatened to, but<br>[37:12] I didn't. I actually did it. And I<br>[37:14] remember that's not for me. And just<br>[37:16] walk off.<br>[37:16] >> I got so desperate that um I'm a cycling<br>[37:20] fan and I was buying a scooter and<br>[37:22] scooter sponsored the tour to France and<br>[37:24] they had like the scooter tour to France<br>[37:27] green jerseys up in the in the thing.<br>[37:30] And I was like, "Okay, would you just<br>[37:32] give me just would can I just have a<br>[37:33] turn of France jersey? Like I'll pay<br>[37:36] full price, but can I just have one of<br>[37:38] those turn?" No, no, you can't have<br>[37:40] that. I was like, "Oh my god." I bought<br>[37:42] the thing. Bought the thing because I<br>[37:43] wanted it and it was a good deal. But<br>[37:46] yeah, but I Yeah, that was that was a<br>[37:48] horrible experience. I just I I felt<br>[37:50] like I was uh just not very skilled that<br>[37:52] Oh, I'm not I'm not skilled at that. I<br>[37:55] should have left that to my wife. She's<br>[37:56] she's really good at that kind of<br>[37:58] >> Yeah, I can imagine she is.<br>[38:01] She loves a haggle.<br>[38:02] >> Yeah. Elliot says, "Not a Black Friday<br>[38:05] related, but I think offering a discount<br>[38:07] for early adopters is a viable reason<br>[38:09] for discounting." I<br>[38:10] >> I like that. I like early.<br>[38:12] >> I don't disagree with you. Yeah. Yeah.<br>[38:14] >> But these are like the nothing to do<br>[38:15] with early adopters. This is just, hey,<br>[38:17] this arbitrary day has happened in the<br>[38:20] year where you can have a discount.<br>[38:23] >> I'll tell you something else. This isn't<br>[38:24] Black Friday related. I used to work for<br>[38:26] Adidas uh in one of their retail<br>[38:28] outlets. Um I was like assistant manager<br>[38:31] of of of the shop. Um and we we were<br>[38:35] just basically told if someone asks for<br>[38:36] a discount, you can give it to them. So<br>[38:39] like you it was just all they have to do<br>[38:42] is say, "Are there any discounts?" And<br>[38:44] you and you could basically make it up<br>[38:46] up to a point. So you could say, "Yeah,<br>[38:47] I'll give you 10% off<br>[38:49] >> or yeah, I'll give you 15% off." Like we<br>[38:52] we had that power. So there is stuff out<br>[38:55] there where if you just ask you will<br>[38:57] get. I was going to say if you don't ask<br>[38:59] you don't get do you?<br>[39:00] >> Yeah. So like you can literally walk up<br>[39:02] to a I don't know if they still do that<br>[39:03] kind of thing. So at Adidas outlet shops<br>[39:05] give it a go. That was a long time ago.<br>[39:07] But uh<br>[39:08] >> but but that's so so if so if I I meet<br>[39:11] up with a friend at night and we've<br>[39:12] we've both been shopping in the day and<br>[39:14] so let's say yourself you've been into<br>[39:16] the adidash shop and you bought a<br>[39:18] beautiful pair of trainers for 100 quid<br>[39:19] and you've asked you say oh is there any<br>[39:21] discounts and yeah oh yeah get 10% off<br>[39:23] then you go so if I buy we bought the<br>[39:25] same product and I've paid 100 quid for<br>[39:27] them because I didn't ask and then we<br>[39:29] both have a chat afterwards. I come away<br>[39:30] with a really bad feeling about that<br>[39:32] company.<br>[39:33] >> Why didn't I get a 10% off? Like we we<br>[39:35] bought at the same time, literally.<br>[39:38] >> So, how's that good?<br>[39:40] >> I don't know. I don't know. I guess like<br>[39:43] No, I guess partly the purpose of an<br>[39:45] outlet shop is to get rid of stuff.<br>[39:47] Like, they're literally just like if you<br>[39:49] can sell it, sell it because, you know,<br>[39:51] this is stuff that's going in the bin<br>[39:53] otherwise. So,<br>[39:54] >> yeah, maybe that's a bit different than<br>[39:55] that sort of type of stuff is. Yeah.<br>[39:58] >> Yeah. Yeah. Yeah.<br>[40:00] got a bit away from the WordPress there,<br>[40:02] but uh but yeah,<br>[40:03] >> as you can tell, I'm not a fan of uh<br>[40:06] discounts and really<br>[40:08] >> Black Fridays and<br>[40:09] >> I think they have their I think they<br>[40:10] have their place, but I do find I do<br>[40:12] find them to be a bit weird sometimes<br>[40:13] and bit arbitrary and<br>[40:15] >> the whole Black Friday thing I find<br>[40:16] absolutely bizarre, but there you go.<br>[40:18] >> Set your price, stick to it, review it<br>[40:21] if it's not working.<br>[40:23] >> Yeah,<br>[40:23] >> that's my that's my my chance.<br>[40:25] >> Early adopters, I'm with Elliot on that.<br>[40:27] I think that's a I think that's a really<br>[40:28] good That's that's a different one. I<br>[40:30] get that. But I think that's a different<br>[40:32] conversation to the one we're having. I<br>[40:33] think if you're starting out, you want<br>[40:35] some that I Yeah, that makes sense. That<br>[40:37] makes sense.<br>[40:37] >> Didn't even get into lifetime discounts.<br>[40:39] Let's not get you started on that.<br>[40:40] Anyway,<br>[40:42] moving on. Moving on. In fact, not<br>[40:44] moving on. Let's finish up there that<br>[40:46] we've done uh done about 40 minutes. Uh<br>[40:49] covered a lot. So, let's finish up for<br>[40:51] this week. As always, thank you so much<br>[40:53] for joining us, for listening, for<br>[40:55] watching. Uh if you do enjoy the show,<br>[40:58] please do consider leaving a little<br>[41:00] like, just click that little thumbs up<br>[41:02] and uh if you want more of this kind of<br>[41:03] thing, you can subscribe and you will<br>[41:05] get notified if you also click the bell<br>[41:07] on YouTube or if you uh follow us on<br>[41:10] your favorite podcast player. Um and if<br>[41:12] you do like it as well, maybe there's<br>[41:14] someone else in your network that would<br>[41:16] enjoy this show. Uh if you could<br>[41:18] possibly just send them a link, uh let<br>[41:20] them know about us, that would be<br>[41:21] superb. Uh are we doing a show next<br>[41:24] week, Mark? Are we? It's getting very<br>[41:26] close to the Christmas holidays. We<br>[41:28] should do<br>[41:29] >> do a little festive number.<br>[41:31] >> Um, so we should be we should be here<br>[41:33] next week. So again, if you want to uh<br>[41:35] get notified of that, please do<br>[41:37] subscribe and hopefully we will see you<br>[41:39] there. Have a great week.<br>[41:41] >> Bye-bye. <!-- deep-read:sections end -->