<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: SiteBrief</title>
    <description>The latest articles on DEV Community by SiteBrief (@sitebrief).</description>
    <link>https://dev.to/sitebrief</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3942839%2F5a42660e-1a45-48c6-b57f-98ea9955eba0.png</url>
      <title>DEV Community: SiteBrief</title>
      <link>https://dev.to/sitebrief</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/sitebrief"/>
    <language>en</language>
    <item>
      <title>Why "flex" breaks your email in Outlook (and how to catch it in VS Code)</title>
      <dc:creator>SiteBrief</dc:creator>
      <pubDate>Tue, 26 May 2026 13:07:35 +0000</pubDate>
      <link>https://dev.to/sitebrief/why-flex-breaks-your-email-in-outlook-and-how-to-catch-it-in-vs-code-h4c</link>
      <guid>https://dev.to/sitebrief/why-flex-breaks-your-email-in-outlook-and-how-to-catch-it-in-vs-code-h4c</guid>
      <description>&lt;p&gt;You spent hours building a beautiful email template with Tailwind CSS.&lt;br&gt;
Flex layout, rounded corners, smooth animations. Looks perfect in the browser.&lt;/p&gt;

&lt;p&gt;Then it lands in Outlook. Complete disaster.&lt;/p&gt;
&lt;h2&gt;
  
  
  The problem
&lt;/h2&gt;

&lt;p&gt;Outlook 2016/2019/2021 uses Microsoft Word as its HTML renderer.&lt;br&gt;
Word doesn't understand modern CSS. At all.&lt;/p&gt;

&lt;p&gt;These Tailwind classes &lt;strong&gt;silently do nothing&lt;/strong&gt; in Outlook:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Class&lt;/th&gt;
      &lt;th&gt;Why it breaks&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;
&lt;code&gt;flex&lt;/code&gt;, &lt;code&gt;inline-flex&lt;/code&gt;
&lt;/td&gt;
      &lt;td&gt;No flexbox support in Outlook Windows&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;
&lt;code&gt;grid&lt;/code&gt;, &lt;code&gt;grid-cols-*&lt;/code&gt;
&lt;/td&gt;
      &lt;td&gt;No CSS Grid support&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code&gt;rounded-*&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;
&lt;code&gt;border-radius&lt;/code&gt; is ignored&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code&gt;animate-*&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;No CSS animations&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code&gt;shadow-*&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;No &lt;code&gt;box-shadow&lt;/code&gt; support&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code&gt;gap-*&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;Requires flex/grid (both unsupported)&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;
&lt;code&gt;w-screen&lt;/code&gt;, &lt;code&gt;h-screen&lt;/code&gt;
&lt;/td&gt;
      &lt;td&gt;No &lt;code&gt;vw&lt;/code&gt;/&lt;code&gt;vh&lt;/code&gt; units&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The worst part? No errors. No warnings. Just broken layouts.&lt;/p&gt;
&lt;h2&gt;
  
  
  The fix
&lt;/h2&gt;

&lt;p&gt;I built an ESLint plugin that catches these issues right in VS Code —&lt;br&gt;
before you send anything.&lt;/p&gt;

&lt;p&gt;bash&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install --save-dev eslint-plugin-email-safe

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// eslint.config.js
import emailSafe from 'eslint-plugin-email-safe'

export default [
  {
    files: ['emails/**/*.{jsx,tsx}'],
    ...emailSafe.configs.recommended,
  }
]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now flex, grid, rounded-lg get underlined instantly:&lt;br&gt;
 "rounded-lg" (border-radius) is not supported in: Outlook Windows.&lt;br&gt;
 Details: &lt;a href="https://www.caniemail.com/features/css-border-radius/" rel="noopener noreferrer"&gt;https://www.caniemail.com/features/css-border-radius/&lt;/a&gt;&lt;br&gt;
89 unsafe patterns detected. Works with cn(), template literals,&lt;br&gt;
and conditional expressions out of the box.&lt;/p&gt;

&lt;p&gt;Bonus: Tailwind plugin with MSO utilities&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install --save-dev tailwind-email-safe
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// tailwind.config.js
module.exports = {
  plugins: [require('tailwind-email-safe')],
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Adds Outlook-safe utilities you actually need:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;table class="email-table w-full max-w-email-md mx-auto"&amp;gt;
  &amp;lt;tr&amp;gt;
    &amp;lt;td class="email-td mso-lh-exact p-6"&amp;gt;
      &amp;lt;img class="email-img" src="logo.png" /&amp;gt;
      &amp;lt;p class="font-email-sans text-base"&amp;gt;Hello!&amp;lt;/p&amp;gt;
    &amp;lt;/td&amp;gt;
  &amp;lt;/tr&amp;gt;
&amp;lt;/table&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;email-table — resets MSO table spacing&lt;/li&gt;
&lt;li&gt;mso-hide — hides element from Outlook only&lt;/li&gt;
&lt;li&gt;mso-lh-exact — fixes line-height in Outlook&lt;/li&gt;
&lt;li&gt;email-img — removes gaps under images&lt;/li&gt;
&lt;li&gt;max-w-email-md — standard 600px email width&lt;/li&gt;
&lt;li&gt;How the compat matrix stays up to date&lt;/li&gt;
&lt;li&gt;The compatibility data comes from caniemail.com.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A weekly AI agent (Claude) monitors Gmail, Outlook, and Apple Mail&lt;br&gt;
release notes for CSS changes. If something changes — it auto-updates&lt;br&gt;
the matrix and opens a PR.&lt;/p&gt;

&lt;p&gt;No manual maintenance needed.&lt;/p&gt;

&lt;p&gt;GitHub: &lt;a href="https://github.com/PasateArtem/email-safe" rel="noopener noreferrer"&gt;https://github.com/PasateArtem/email-safe&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Free and open source. Would love feedback from people building emails!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqx9ru7y214xvboz2qkyv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqx9ru7y214xvboz2qkyv.png" alt=" " width="800" height="307"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi45pxo6wsyjrr5fy6pbf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi45pxo6wsyjrr5fy6pbf.png" alt=" " width="800" height="484"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsbjl1i13xr44jjq1tmd8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsbjl1i13xr44jjq1tmd8.png" alt=" " width="800" height="422"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>github</category>
      <category>tailwindcss</category>
      <category>eslint</category>
      <category>outlook</category>
    </item>
    <item>
      <title>I built a tool that detects broken security headers, missing robots.txt, and WP_DEBUG=true — then opens a PR to fix them automatically</title>
      <dc:creator>SiteBrief</dc:creator>
      <pubDate>Thu, 21 May 2026 16:20:43 +0000</pubDate>
      <link>https://dev.to/sitebrief/i-built-a-tool-that-detects-broken-security-headers-missing-robotstxt-and-wpdebugtrue-then-23jd</link>
      <guid>https://dev.to/sitebrief/i-built-a-tool-that-detects-broken-security-headers-missing-robotstxt-and-wpdebugtrue-then-23jd</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5066qi6y0gtbklee9rji.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5066qi6y0gtbklee9rji.png" alt=" " width="800" height="441"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Every agency I've talked to has the same story.&lt;/p&gt;

&lt;p&gt;Client calls on a Friday. Site is down or flagged by Google Search Console. You SSH in, find WP_DEBUG = true in production, turn it off, deploy, done. Twenty minutes gone. Next week, different client, same thing.&lt;/p&gt;

&lt;p&gt;I run a small web agency tool called SiteBrief — it monitors uptime, SSL, PageSpeed, SEO, and security headers across client sites. After six months of watching the same issues appear on the same types of sites, I built DevLab: a section that not only detects problems but generates the fix and opens a GitHub PR (or GitLab MR) for your review.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;The workflow&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Detect → Explain → Preview fix → Open PR → You approve&lt;/code&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Detect — SiteBrief continuously scans for security header gaps, SEO problems, PageSpeed issues, WordPress misconfigs, broken crawl settings&lt;/li&gt;
&lt;li&gt;Explain — every issue gets a plain-English description, severity level, and a confidence score (more on that below)&lt;/li&gt;
&lt;li&gt;Preview fix — click "Preview fix" and you see the exact file, the exact change, and what it will do — before anything happens&lt;/li&gt;
&lt;li&gt;Open PR — confirm in the modal, SiteBrief opens a pull request on your repo with a descriptive title, full context in the body, and a dedicated fix branch&lt;/li&gt;
&lt;li&gt;You approve — review the diff on GitHub/GitLab as you normally would. Nothing merges automatically.&lt;/li&gt;
&lt;/ol&gt;




&lt;p&gt;&lt;strong&gt;Confidence scores&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This was the part I spent the most time thinking about. "AI generates fixes" sounds scary. The honest answer is: some fixes are deterministic (swap true for false in one line), others are educated guesses (write an SEO title for a site you've never seen).&lt;/p&gt;

&lt;p&gt;So every fix has a confidence score:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;| Issue                        | Fix                                      | Confidence |
|------------------------------|------------------------------------------|------------|
| WP_DEBUG = true              | define('WP_DEBUG', false) in wp-config   | 95%        |
| robots.txt missing           | Valid file with User-agent: &lt;span class="err"&gt;*&lt;/span&gt; / Allow: / | 90%        |
| Missing security headers     | HSTS, X-Frame-Options, CSP               | 88%        |
| Missing viewport / canonical | Correct meta tag added                   | 85%        |
| No cache headers             | Cache-Control: max-age=31536000          | 75%        |
| Missing SEO title/desc       | Placeholder — needs your review          | 62%        |
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Green (≥85%) = safe to merge after a quick look. Amber (≥70%) = test on staging. Orange (&amp;lt;70%) = treat as a starting point, edit before merging.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Auto-detecting the right file&lt;/strong&gt;&lt;br&gt;
One thing I didn't want to do: assume everyone is on Netlify.&lt;/p&gt;

&lt;p&gt;When DevLab generates a security header fix, it reads your repo and tries candidate files in order:&lt;/p&gt;

&lt;p&gt;netlify.toml → adds a [[headers]] block&lt;br&gt;
.htaccess → adds Header always set inside mod_headers&lt;br&gt;
nginx.conf (or nginx/default.conf) → injects add_header into the server block&lt;br&gt;
For SEO fixes it detects the framework:&lt;/p&gt;

&lt;p&gt;Next.js App Router → edits app/layout.tsx using the metadata export&lt;br&gt;
Plain HTML → injects  tags into &lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Why I built the preview step&lt;/strong&gt;&lt;br&gt;
My first instinct was to make "Generate PR" a single button. Ship it, done.&lt;/p&gt;

&lt;p&gt;Then I showed it to three agency owners. All three asked: "But what exactly is it going to change?" That was the signal. Nobody wants a black box touching client repos.&lt;/p&gt;

&lt;p&gt;So now the flow is:&lt;/p&gt;

&lt;p&gt;Click "Preview fix"&lt;br&gt;
Modal shows: action description, exact file path, confidence bar with color coding, a safety note ("this adds headers to netlify.toml — it will not touch your application code"), and the "Nothing merges automatically" guarantee&lt;br&gt;
Click "Open PR" to proceed — or just close the modal&lt;br&gt;
The PR opens on a dedicated branch (sitebrief/fix-security-headers style), so it's isolated and easy to close if you change your mind.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;One-click rollback&lt;/strong&gt;&lt;br&gt;
If you open a PR and then decide against it, there's a Close button directly in the DevLab history panel. It calls GitHub's PATCH /pulls/{number} (state: closed) or GitLab's PUT /merge_requests/{iid} (state_event: close) and marks the fix as rolled back in our records.&lt;/p&gt;

&lt;p&gt;No need to go to GitHub just to close a PR.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;What's next&lt;/strong&gt;&lt;br&gt;
Short-term:&lt;/p&gt;

&lt;p&gt;Staging branch deploys — open the fix PR against a staging branch, not main&lt;br&gt;
Dependency security updates — scan package.json / composer.json, PR with safe version bumps&lt;br&gt;
Scheduled digest — weekly email: all issues + open fix PRs across your portfolio&lt;/p&gt;

&lt;p&gt;If you run a dev shop with multiple client sites and you're tired of playing whack-a-mole with the same misconfigs every month — that's exactly who DevLab is for.&lt;/p&gt;

&lt;p&gt;Happy to answer questions about the implementation, the PR flow, or how the file detection works.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://sitebrief.net/" rel="noopener noreferrer"&gt;https://sitebrief.net/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>github</category>
      <category>devops</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Why your clients find out about site downtime before you do</title>
      <dc:creator>SiteBrief</dc:creator>
      <pubDate>Wed, 20 May 2026 19:03:40 +0000</pubDate>
      <link>https://dev.to/sitebrief/why-your-clients-find-out-about-site-downtime-before-you-do-584i</link>
      <guid>https://dev.to/sitebrief/why-your-clients-find-out-about-site-downtime-before-you-do-584i</guid>
      <description>&lt;p&gt;It's 9:07 AM on a Tuesday. Your phone rings. It's a client.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;"Hey, our website is down. Has been for a couple hours. Can you look into it?"&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You open your laptop, type in the URL, and there it is — a blank white page, or worse, a 500 error. The client knew before you did. Again.&lt;/p&gt;

&lt;h2&gt;
  
  
  The real reason clients find out first
&lt;/h2&gt;

&lt;p&gt;It's not because you're bad at your job. It's because you're not watching every site, every minute of every day. That's not humanly possible.&lt;/p&gt;

&lt;p&gt;Clients visit their own site constantly — first thing in the morning, before a meeting, after sending someone a link. The moment something breaks, they see it. Meanwhile, you might not check a client's site for days unless there's a reason to.&lt;/p&gt;

&lt;p&gt;That's the gap — and it costs you trust every single time.&lt;/p&gt;

&lt;h2&gt;
  
  
  What makes it worse: silent downtime
&lt;/h2&gt;

&lt;p&gt;Not all downtime is dramatic. Sometimes the site looks fine but returns a 500 error on certain pages. Sometimes an SSL certificate expired and Chrome shows a red warning — visitors leave, but you had no idea.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A plugin update broke the checkout — but not the homepage&lt;/li&gt;
&lt;li&gt;A hosting provider had a partial outage affecting only certain regions&lt;/li&gt;
&lt;li&gt;The domain renewal lapsed and the site stopped loading&lt;/li&gt;
&lt;li&gt;WP_DEBUG was accidentally left on, leaking database errors in the page source&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These slip through without monitoring. By the time someone notices, it's been hours.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to get ahead of it
&lt;/h2&gt;

&lt;p&gt;You need to be notified the moment something goes wrong — before anyone else sees it.&lt;/p&gt;

&lt;p&gt;For agencies managing multiple client sites, the checklist:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Uptime monitoring&lt;/strong&gt; — checks every minute from multiple locations, alerts within seconds&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SSL &amp;amp; domain expiry&lt;/strong&gt; — alerts 30 days before anything expires&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Response time tracking&lt;/strong&gt; — catch slow sites before clients notice performance issues&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;WordPress health&lt;/strong&gt; — outdated plugins, PHP version, WP_DEBUG status, health score 0–100 per site&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Maintenance task board&lt;/strong&gt; — when something breaks, create a task right from the alert&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The business case
&lt;/h2&gt;

&lt;p&gt;When you catch an issue before the client does, you're not firefighting — you're delivering value. Monthly uptime reports, proactive plugin updates, SSL renewals handled weeks early. That's what justifies a retainer.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Agencies that monitor proactively charge more, retain clients longer, and spend less time on damage control.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I built &lt;a href="https://sitebrief.net" rel="noopener noreferrer"&gt;SiteBrief&lt;/a&gt; to solve exactly this. Free plan covers 20 sites, no credit card needed.&lt;/p&gt;

&lt;p&gt;What's your current monitoring setup? Would love to hear how others handle this.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>saas</category>
      <category>monitoring</category>
      <category>analytics</category>
    </item>
  </channel>
</rss>
