<?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: Oscar Villegas</title>
    <description>The latest articles on DEV Community by Oscar Villegas (@oscarvillegas).</description>
    <link>https://dev.to/oscarvillegas</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.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4175644%2Fe72a1f2d-a8ea-4c3f-8505-7a420b2d590e.jpg</url>
      <title>DEV Community: Oscar Villegas</title>
      <link>https://dev.to/oscarvillegas</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/oscarvillegas"/>
    <language>en</language>
    <item>
      <title>Meta Pixel Counting Purchases Twice: Causes and How to Fix Duplicates</title>
      <dc:creator>Oscar Villegas</dc:creator>
      <pubDate>Sat, 10 Oct 2026 16:52:36 +0000</pubDate>
      <link>https://dev.to/oscarvillegas/meta-pixel-counting-purchases-twice-causes-and-how-to-fix-duplicates-4o95</link>
      <guid>https://dev.to/oscarvillegas/meta-pixel-counting-purchases-twice-causes-and-how-to-fix-duplicates-4o95</guid>
      <description>&lt;p&gt;Meta counts a purchase twice when the same sale reaches it from two places without a shared event_id, for example the pixel and the Conversions API, or two apps or plugins that both send Purchase. It also happens when customers return to the thank-you page from an external payment page and the pixel fires again. The fix is one source per event and the same event_id on the browser and the server event.&lt;/p&gt;

&lt;h2&gt;
  
  
  The usual causes
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Pixel and Conversions API both send Purchase, but without the same event_id, so Meta cannot tell they are the same sale.&lt;/li&gt;
&lt;li&gt;Two tools send the event: a platform app plus a plugin, or an app plus Google Tag Manager.&lt;/li&gt;
&lt;li&gt;The thank-you page loads twice: after an external payment, a refresh or a return from the payment provider.&lt;/li&gt;
&lt;li&gt;The Purchase event is set on a page that also loads for other actions.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How to check it
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Compare one week of real orders against the purchases in Events Manager.&lt;/li&gt;
&lt;li&gt;In Events Manager, open the Purchase event and look at how many events arrive from the browser and from the server, and the deduplication status.&lt;/li&gt;
&lt;li&gt;Use the Test Events tool, make one test purchase and count how many Purchase events arrive.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How to fix it
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Leave a single tool sending each event to Meta.&lt;/li&gt;
&lt;li&gt;Send the same event_id, usually the order ID, with the browser event and the server event.&lt;/li&gt;
&lt;li&gt;Fire Purchase only once per order, for example by checking the order ID before sending.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Will Shopify, Meta and Google ever match exactly?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;No. Each platform counts in its own way. A small, stable gap is normal; a gap above about 20% usually means something is broken.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Does deduplication need the Conversions API?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Deduplication matters when you send events from both the browser and the server. With the pixel only, duplicates come from double firing on the page.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://oscarvillegas.online/guides/meta-pixel-duplicate-purchases" rel="noopener noreferrer"&gt;oscarvillegas.online&lt;/a&gt;.&lt;/em&gt; I'm Oscar Villegas and I fix this kind of problem for a fixed price: &lt;a href="https://oscarvillegas.online/server-side-tracking/meta-conversions-api" rel="noopener noreferrer"&gt;Meta Conversions API&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>meta</category>
      <category>analytics</category>
      <category>ecommerce</category>
      <category>tracking</category>
    </item>
    <item>
      <title>'There Has Been a Critical Error on This Website' in WordPress: How to Fix It</title>
      <dc:creator>Oscar Villegas</dc:creator>
      <pubDate>Sat, 10 Oct 2026 16:46:33 +0000</pubDate>
      <link>https://dev.to/oscarvillegas/there-has-been-a-critical-error-on-this-website-in-wordpress-how-to-fix-it-4h9p</link>
      <guid>https://dev.to/oscarvillegas/there-has-been-a-critical-error-on-this-website-in-wordpress-how-to-fix-it-4h9p</guid>
      <description>&lt;p&gt;"There has been a critical error on this website" means PHP hit a fatal error, almost always right after a plugin, theme or PHP version update. WordPress usually emails the site administrator a recovery mode link that names the plugin or theme that failed. Log in through that link, deactivate or roll back that plugin, and the site comes back; then find the real cause in the error log before updating again.&lt;/p&gt;

&lt;h2&gt;
  
  
  Find what broke
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Check the administrator email inbox, and the spam folder, for the message from WordPress with the recovery mode link.&lt;/li&gt;
&lt;li&gt;If there is no email, look at the PHP error log in your hosting panel. The last fatal error names the file, and the folder name tells you the plugin or theme.&lt;/li&gt;
&lt;li&gt;If you cannot see logs, rename the plugin's folder in wp-content/plugins through FTP or the file manager. That deactivates it.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Fix it without losing content
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Take a backup before changing anything.&lt;/li&gt;
&lt;li&gt;Roll back the plugin or theme to the previous version, or deactivate it until there is a fix.&lt;/li&gt;
&lt;li&gt;If the error started after changing the PHP version, check which plugin is not compatible with it.&lt;/li&gt;
&lt;li&gt;Update again only after confirming compatibility, ideally on a copy of the site first.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Will I lose my content?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;No. The error stops the page from loading but does not delete posts, pages or orders.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why did it happen if I did not change anything?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Automatic updates of plugins, themes or PHP by the hosting can trigger it without anyone touching the site.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://oscarvillegas.online/guides/wordpress-critical-error" rel="noopener noreferrer"&gt;oscarvillegas.online&lt;/a&gt;.&lt;/em&gt; I'm Oscar Villegas and I fix this kind of problem for a fixed price: &lt;a href="https://oscarvillegas.online/wordpress-fix" rel="noopener noreferrer"&gt;WordPress repair&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>wordpress</category>
      <category>php</category>
      <category>webdev</category>
      <category>debugging</category>
    </item>
    <item>
      <title>Google Ads 'Compromised Site' Disapproval: How to Fix It and Get Ads Approved</title>
      <dc:creator>Oscar Villegas</dc:creator>
      <pubDate>Sat, 10 Oct 2026 16:43:08 +0000</pubDate>
      <link>https://dev.to/oscarvillegas/google-ads-compromised-site-disapproval-how-to-fix-it-and-get-ads-approved-1jg0</link>
      <guid>https://dev.to/oscarvillegas/google-ads-compromised-site-disapproval-how-to-fix-it-and-get-ads-approved-1jg0</guid>
      <description>&lt;p&gt;Google Ads disapproves ads with "Compromised site" when it finds malware or hacked content on the landing page or on the domain. The ads cannot run again until the site is clean, so an appeal sent before cleaning it is rejected. Clean the site first, confirm it in Google Search Console, and then request the review from the Policy manager in Google Ads.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Google found
&lt;/h2&gt;

&lt;p&gt;The policy covers sites that were hacked to add malware, unwanted redirects, spam pages or code that harms visitors. Google may detect it on the exact landing page or on another page of the same domain, so a landing page that looks fine can still be disapproved.&lt;/p&gt;

&lt;h2&gt;
  
  
  Steps to get the ads running again
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Check Google Search Console under Security issues for the URLs and the type of problem Google reported.&lt;/li&gt;
&lt;li&gt;Clean the whole site, not only the landing page: files, database and any redirect.&lt;/li&gt;
&lt;li&gt;Change every password and update WordPress, plugins and themes.&lt;/li&gt;
&lt;li&gt;Request a review in Search Console once the site is clean.&lt;/li&gt;
&lt;li&gt;In Google Ads, open the Policy manager, select the disapproved ads and request a review.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  While you wait
&lt;/h2&gt;

&lt;p&gt;If the business depends on those ads, you can point the campaigns to a clean landing page on a different domain or subdomain that is not affected, as long as it is a real page of your business and complies with Google Ads policies.&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Can I just appeal without cleaning the site?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The appeal is rejected if Google still finds the problem, and repeated rejections only delay the ads. Clean first, then appeal.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How long does the review take?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It varies. Google often answers within a few days once the site is clean.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://oscarvillegas.online/guides/google-ads-compromised-site" rel="noopener noreferrer"&gt;oscarvillegas.online&lt;/a&gt;.&lt;/em&gt; I'm Oscar Villegas and I fix this kind of problem for a fixed price: &lt;a href="https://oscarvillegas.online/wordpress-fix/hacked-site" rel="noopener noreferrer"&gt;Hacked WordPress site&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>wordpress</category>
      <category>security</category>
      <category>malware</category>
      <category>webdev</category>
    </item>
    <item>
      <title>WordPress Site Redirects to a Spam Site: Why It Happens and How to Fix It</title>
      <dc:creator>Oscar Villegas</dc:creator>
      <pubDate>Sat, 10 Oct 2026 16:35:15 +0000</pubDate>
      <link>https://dev.to/oscarvillegas/wordpress-site-redirects-to-a-spam-site-why-it-happens-and-how-to-fix-it-4hn3</link>
      <guid>https://dev.to/oscarvillegas/wordpress-site-redirects-to-a-spam-site-why-it-happens-and-how-to-fix-it-4hn3</guid>
      <description>&lt;p&gt;When a WordPress site redirects to a spam site, malicious code was added to the site, and it often redirects only visitors who come from Google or from a phone, so the owner does not see it. The code is usually hidden in .htaccess, in wp-config.php or a theme file, in the database (site URL options or injected scripts in posts), or in a fake plugin. Removing only the redirect is not enough; the backdoor that added it has to go too.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why you may not see the redirect
&lt;/h2&gt;

&lt;p&gt;Attackers want the redirect to last, so they hide it from the site owner. Common conditions are: only visitors coming from a search engine, only phones, only the first visit, or never when you are logged in to WordPress. Test from your phone with mobile data, opening the site from a Google search result, in a private window.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where the redirect is usually hidden
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;.htaccess: rewrite rules that send search engine visitors to another domain.&lt;/li&gt;
&lt;li&gt;wp-config.php, functions.php or index.php: obfuscated PHP, often long strings with base64_decode, eval or gzinflate.&lt;/li&gt;
&lt;li&gt;The database: changed siteurl or home options, or script tags injected in posts, widgets and options.&lt;/li&gt;
&lt;li&gt;A fake plugin with a plausible name that does not appear in the plugins list.&lt;/li&gt;
&lt;li&gt;JavaScript added to the theme or to a cached file that loads the redirect from an external domain.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How to fix it properly
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Take a full backup of files and database first.&lt;/li&gt;
&lt;li&gt;Change all passwords and remove unknown admin users.&lt;/li&gt;
&lt;li&gt;Replace WordPress core with a clean copy and reinstall plugins and themes from official sources.&lt;/li&gt;
&lt;li&gt;Search the database for script tags and external domains you do not recognize, and check the siteurl and home options.&lt;/li&gt;
&lt;li&gt;Check .htaccess and every PHP file in uploads, then update everything and remove plugins you do not use.&lt;/li&gt;
&lt;li&gt;Request a review in Google Search Console if Google flagged the site.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Why does the redirect only happen on mobile?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Many redirect scripts check the device or the referrer on purpose, so the site owner, usually on a computer and logged in, never sees it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;I removed the code and it came back. Why?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;There is a backdoor somewhere else that writes the redirect again, or another infected site on the same hosting account. The cleanup has to cover files, database and every site in the account.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://oscarvillegas.online/guides/wordpress-redirects-to-spam" rel="noopener noreferrer"&gt;oscarvillegas.online&lt;/a&gt;.&lt;/em&gt; I'm Oscar Villegas and I fix this kind of problem for a fixed price: &lt;a href="https://oscarvillegas.online/wordpress-fix/hacked-site" rel="noopener noreferrer"&gt;Hacked WordPress site&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>wordpress</category>
      <category>security</category>
      <category>malware</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Is My WordPress Site Hacked? 9 Signs of Malware and What to Do First</title>
      <dc:creator>Oscar Villegas</dc:creator>
      <pubDate>Sat, 10 Oct 2026 16:34:34 +0000</pubDate>
      <link>https://dev.to/oscarvillegas/is-my-wordpress-site-hacked-9-signs-of-malware-and-what-to-do-first-29ki</link>
      <guid>https://dev.to/oscarvillegas/is-my-wordpress-site-hacked-9-signs-of-malware-and-what-to-do-first-29ki</guid>
      <description>&lt;p&gt;A WordPress site is probably hacked if visitors get redirected to spam, Google shows "This site may be hacked", you find administrator users you did not create, or new PHP files appear in the uploads folder. If you see any of these, do not delete things at random: take a full backup first, change every password and then clean the files and the database, because a partial cleanup usually leaves a backdoor that reinfects the site.&lt;/p&gt;

&lt;h2&gt;
  
  
  The 9 most common signs
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Visitors, or only mobile visitors coming from Google, are redirected to casino, pharmacy or adult sites, while the site looks normal when you type the address yourself.&lt;/li&gt;
&lt;li&gt;Searching site:yourdomain.com on Google shows pages you never wrote, often in Japanese or full of pharmacy keywords.&lt;/li&gt;
&lt;li&gt;Google shows "This site may be hacked" under your result, or Chrome shows a red "Deceptive site ahead" page.&lt;/li&gt;
&lt;li&gt;Google Ads disapproves your ads with the policy "Compromised site".&lt;/li&gt;
&lt;li&gt;There are administrator users you did not create in Users, or your password suddenly stopped working.&lt;/li&gt;
&lt;li&gt;New PHP files appear in wp-content/uploads, a folder that should only hold images and documents.&lt;/li&gt;
&lt;li&gt;Plugins you never installed, or plugins that reappear after you delete them.&lt;/li&gt;
&lt;li&gt;Your hosting suspends the account, warns you about malware or says the site is sending spam email.&lt;/li&gt;
&lt;li&gt;The site became very slow or the server CPU is at 100% with no extra traffic.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What to do first, in this order
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Take a full backup of files and database as they are now. It keeps your content safe and shows later how they got in.&lt;/li&gt;
&lt;li&gt;Change every password: WordPress admins, hosting panel, FTP and the database user. Remove any admin user you do not recognize.&lt;/li&gt;
&lt;li&gt;Check Google Search Console under Security issues to see what Google found and on which URLs.&lt;/li&gt;
&lt;li&gt;Do not just install a security plugin and call it done. Scanners find known patterns, but backdoors are often hidden in files that look normal.&lt;/li&gt;
&lt;li&gt;Clean the site completely: replace WordPress core with a fresh copy, reinstall plugins and themes from official sources, and check the uploads folder and the database for injected code.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How they usually get in
&lt;/h2&gt;

&lt;p&gt;In our experience the most common entry point is an outdated plugin or theme with a known security hole. Next come pirated themes that already include a backdoor, passwords reused from another service, and other infected sites in the same hosting account. Closing that hole is what keeps the site clean after the cleanup.&lt;/p&gt;

&lt;h2&gt;
  
  
  When to ask for help
&lt;/h2&gt;

&lt;p&gt;If the redirects come back after you clean them, if you cannot log in, or if your Google Ads are stopped, the infection usually has more than one backdoor. That is the point where a full cleanup by someone who reads the server logs saves time and ad spend.&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Can a security plugin remove the malware by itself?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Sometimes, for simple infections. Many hacks leave backdoors in files that look normal, so a plugin can report the site as clean while the attacker can still get in.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Will I lose my posts or orders if I clean the site?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;No. A proper cleanup keeps posts, pages, products and orders. It removes infected files and injected code, after a full backup.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How long until Google removes the hacked warning?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;After the site is clean you request a review in Search Console. Google usually answers within a few days.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://oscarvillegas.online/guides/wordpress-hacked-signs" rel="noopener noreferrer"&gt;oscarvillegas.online&lt;/a&gt;.&lt;/em&gt; I'm Oscar Villegas and I fix this kind of problem for a fixed price: &lt;a href="https://oscarvillegas.online/wordpress-fix/hacked-site" rel="noopener noreferrer"&gt;Hacked WordPress site&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>wordpress</category>
      <category>security</category>
      <category>malware</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
