Most privacy problems on small business websites do not start with a deliberate decision about advertising or analytics. They start casually: someone embeds a map so customers can find the yard. Someone puts a company video on the home page. A typeface comes from its vendor's server, an icon pack from a delivery network. None of those decisions feels like data processing — technically, every one of them is. The visitor's browser opens a connection to a third-party server, and her IP address travels with it, together with a browser signature and the address of the page she is on. This happens before any consent dialog becomes visible, and it happens on every single page view. This article shows how to find such embeds with nothing but the browser, and in which order to replace them: serve fonts yourself, rebuild directions as your own illustration plus a route link, put a preview image and a click-to-load step in front of video, and inline your icons. The side effect is pleasant — the page opens fewer foreign connections and calms down.
The real leak sits in the page head
A website is not a self-contained file, it is a set of build instructions. The browser reads the HTML document, finds references to images, stylesheets, fonts, scripts and embedded frames, and fetches each of those resources separately. If one of those references points at a foreign domain, the request goes to that vendor's server rather than yours. And what travels is more than a request for a file. Every request necessarily carries the IP address of the connection it comes from, in practice a browser and operating system signature, often the address of the page the request originates from, and depending on the setup any cookies already set for that foreign domain. The recipient does not have to do anything to obtain this: those details are the precondition for a response to be deliverable at all.
This is common to a degree that makes the exception the rule. In the HTTP Archive's Web Almanac, an annual analysis of millions of real pages, 92 percent (HTTP Archive Web Almanac) of pages examined contain at least one resource from a third-party domain. Among pages in the top million, the median is 27 (HTTP Archive Web Almanac) distinct third parties per page. Resources from googleapis.com alone — the domain that serves fonts, among other things — appear on 69 percent (HTTP Archive Web Almanac) of desktop pages examined and 68 percent (HTTP Archive Web Almanac) of mobile ones. And 95 percent (HTTP Archive Web Almanac) of desktop pages contain at least one element the analysis classifies as a tracker.
What this article deliberately does not cover
In practice the same six patterns keep showing up. They differ a lot in how much work replacing them takes, but not in how they are assessed legally: each one opens a connection to a foreign server the moment somebody opens the page.
- Fonts from a font service, referenced as a stylesheet link in the page head or as an
@importburied in your own CSS file. - Maps as an embedded frame on the contact or directions page, usually copied straight out of a map provider's share dialog.
- Videos as an embedded player that loads during page build, even when nobody clicks play.
- Icon packs and symbol fonts that ship an entire alphabet of pictograms in one file — for six symbols you actually use.
- JavaScript libraries from a delivery network: carousels, form helpers, animation tools, often leftovers from an old template.
- Widgets of every kind: review stars, booking calendars, chat windows, weather panels, social media buttons.
What courts and supervisory authorities say about it
Two sets of rules interlock here, and they test different things. Section 25 of the German Telecommunications and Digital Services Data Protection Act governs access to the end device: storing information on the device and accessing information already stored there is only permitted with consent — unless the operation serves solely to transmit a message, or is strictly necessary to provide a service the user has explicitly requested (TDDDG, Section 25). The General Data Protection Regulation separately governs the processing of the data itself. That includes transmitting the IP address to a foreign server even when not a single cookie is set. Passing the first test still leaves the second one ahead of you.
Embedding third-party content on websites regularly entails a disclosure of personal data to the operators of the respective third-party server. Under Article 6(1) GDPR, a legal basis is required for this processing. Typical examples of such third-party content are advertisements, fonts, scripts, city maps, videos, photos or content from social media services.
How concrete this can get is shown by a ruling of the Munich Regional Court I. A site operator had loaded a typeface dynamically from the vendor's server, which transmitted every visitor's IP address there. The court found this to infringe the general right of personality and awarded the claimant 100 euros (Munich Regional Court I, case no. 3 O 17493/20) in damages, plus an injunction (Munich Regional Court I, case no. 3 O 17493/20). Two elements of the reasoning reach beyond the individual case. First, the dynamic IP address was classified as personal data, because the operator has legal means to have the person behind it identified. Second, the transfer to a server in the United States mattered, for which no adequate level of protection had been established at the time (Munich Regional Court I, case no. 3 O 17493/20). The ruling is uncomfortable in practice precisely because a data-frugal alternative is right there: serving the same font from your own domain is not an elaborate workaround, it is the ordinary way of doing it.
The second landmark decision comes from the Court of Justice of the European Union. It is older but more fundamental. In the Fashion ID case, brought by the consumer association Verbraucherzentrale North Rhine-Westphalia, the subject was a social media button on a fashion retailer's website. The Court found that personal data was transmitted to the button's provider when the site was loaded, „without that visitor being aware of it and regardless of whether or not he or she is a member of the social network Facebook or has clicked on the ‚Like‘ button“ (CJEU, C-40/17). The site operator was held to be a joint controller — but in a limited way: not for whatever the provider does with the data afterwards, but for „the collection of the personal data of visitors to its website and their disclosure by transmission“ (CJEU, C-40/17). That is exactly the part the operator decides on, by placing the embed.
It is therefore the operator of the website, and not the provider of the social plugin, who must obtain that consent, since it is the fact that a visitor consults that website that triggers the processing of the personal data.
The reasoning carries over to maps, videos and fonts without any strain: there too, the page load alone triggers the transmission, there too the person has no idea, and there too the operator decides whether that connection exists at all. The German Data Protection Conference draws a practical conclusion about timing from this. Additional services such as a map service, a chat or a contact form are, on their reading, not requested simply by opening the page: users „request“ such functions only once they explicitly make use of them (German Data Protection Conference, guidance for providers of telemedia services). Access may therefore begin only when the function is actually used — not merely because it exists somewhere on the page.
Third-country transfer comes on top
| Embed | What reaches the foreign server | Data-frugal alternative |
|---|---|---|
| Font via a stylesheet reference | IP address, browser signature, page requested — on every single visit | Copy the font files into your own domain and use @font-face |
| Embedded map | IP address, browser signature, frequently cookies of the map provider | Your own directions panel plus a link to a route planner |
| Embedded video player | IP address and player data, even without a click on play | Preview image with click-to-load, player only loads afterwards |
| Icon pack from a delivery network | IP address, browser signature, reference to the subpage requested | Only the symbols you use, inlined as SVG in the HTML |
| Library from a delivery network | IP address and the full request context, often on every page | Download the file once and ship it with your own files |
Step one: measure your own site instead of guessing
Before anything gets replaced, you need a list. It comes out of two passes, and neither needs extra tooling. The first pass is the network analysis in the browser: every mainstream browser ships developer tools with a panel that logs each request made while the page is built — with target domain, file type and size. The second pass is a source search. It catches references that slip past the network log because they only load under certain conditions or after an interaction.
- Open the page in a private window so that old cookies and cached files do not distort the picture.
- Open the developer tools — in mainstream browsers via the F12 key or the menu for more tools — and switch to the network panel.
- Reload the page and sort the list by domain. Anything that does not point at your own domain goes on the list.
- Repeat this for each type of page: home page, a services page, the contact page with the map, a page with video, the blog section. Embeds are rarely distributed evenly.
- Second pass: open the source and search for
iframe,@import,preconnect,dns-prefetchand for//in combination with domains you do not own. - Record the result in a plain table: domain, page affected, purpose, planned replacement. That table doubles as the record your accountability obligation calls for.
Domain Type Purpose on the page Assessment
---------------------------------------------------------------------------------
your-domain.com document the page itself fine
your-domain.com img, css own media fine
fonts.third-party.com css, font heading typeface replace: self-host
maps.third-party.com iframe directions, contact page replace: image + route link
video.third-party.com script company video, home replace: click-to-load
cdn.third-party.com script leftover from a template remove
icons.third-party.com css, font six symbols replace: inline SVGThe pass almost everyone skips
After that the list usually sorts itself into three groups. Some entries have an obvious purpose and an obvious replacement that changes nothing visible — fonts and icons belong here. A second group provides real value you do not want to drop: map and video. A third group is simply legacy — libraries an earlier template brought along that no longer serve any function. The third group is the most rewarding, because deleting is the complete solution. Start with the first anyway: it delivers the largest effect for the least amount of discussion.
Fonts: the best ratio of effort to effect
Web fonts are the norm today: 87 percent (HTTP Archive Web Almanac) of all websites examined use at least one. How they are obtained, however, is very unevenly distributed. Only 28 percent (HTTP Archive Web Almanac) of desktop pages and 34 percent (HTTP Archive Web Almanac) of mobile pages serve their fonts exclusively themselves; 57 percent (HTTP Archive Web Almanac) of desktop pages load at least one font from one of the large font services. The switch is nevertheless the easiest item on the whole list, because nothing changes about the visible result: same typeface, same weights, same look — just a different source.
Legally the route is uncomplicated for the widely used open font families, because their licences explicitly permit redistribution and self-hosting. For purchased typefaces it is worth reading the licence to see whether web font use on your own servers is included; many foundries include it, some sell it as a separate component. Technically, though, the expectation of a speed gain deserves an honest framing: web.dev states that a self-hosted font should on paper deliver better performance because it eliminates a third-party connection setup, but that in practice the differences are less clear cut and depend on how your own files are delivered (web.dev). The privacy gain depends on no measurement at all — it consists in the connection no longer existing.
- Establish which font families and weights are actually in use. In practice it is almost always fewer than are embedded — three weights are enough for most business sites.
- Obtain the font files in WOFF2. It is the common format on 81 percent (HTTP Archive Web Almanac) of desktop pages and compresses around 30 percent (web.dev) better than the older WOFF.
- Put the files in a directory of their own, for instance
/fonts/, and serve them with a long cache lifetime — the file will practically never change. - Add
@font-facerules in your own stylesheet and setfont-display: swap. Without it, mainstream browsers block text rendering for up to three seconds (web.dev); only 44 percent (HTTP Archive Web Almanac) of desktop pages use it. - Remove the old reference to the font service — including the accompanying
preconnectanddns-prefetchlines in the page head, which otherwise keep opening the connection anyway. - Repeat the network analysis. No foreign font domain may appear in the list any more, not even as a bare connection without a file.
/* Font from your own domain instead of a third-party font service */
@font-face {
font-family: "Example Sans";
src: url("/fonts/example-sans-400.woff2") format("woff2");
font-weight: 400;
font-style: normal;
font-display: swap;
}
@font-face {
font-family: "Example Sans";
src: url("/fonts/example-sans-700.woff2") format("woff2");
font-weight: 700;
font-style: normal;
font-display: swap;
}
/* These lines have to go as well - they keep opening the connection:
<link rel="preconnect" href="https://fonts.third-party.com">
@import url("https://fonts.third-party.com/css?family=..."); */The two leftovers that like to stay
@import in the middle of an old CSS file: the network analysis shows it, the page head does not contain it, and searching the HTML for the word „font“ finds nothing. The second is a symbol font that is technically loaded as a font although it delivers pictograms — it turns up in the same search and belongs in the same work step. Both cost one line of work each, and they are the reason the network analysis belongs after the switch rather than being ticked off in advance.One final point about font choice that is often overlooked: fewer weights mean fewer files, shorter loading time and less shifting in the layout. Embedding a family in eight weights while using two of them means downloading six files for nothing. And when a typeface is only needed for headings, it can be reduced to the characters actually required — web.dev notes that removing unused glyphs significantly reduces the file size (web.dev). How text volume and readability interact is covered in the article on writing website copy people actually read.
Directions: a map that reports nobody
The embedded map on the contact page is the second most common find and the most emotional one: it is visible, it feels helpful, and nobody wants to lose it without a replacement. The reflex of simply putting it behind the consent dialog is legally defensible but weak in practice. People who land on the contact page are looking for an address — and the first thing they see is a grey rectangle with a consent notice. So the step before is worth taking: asking what visitors actually need at that spot. That the contact page belongs to the set of pages no business website should skip is covered in the article on which pages a business website needs.
The honest answer is rarely „a zoomable map“. What people need is the full address in a form they can copy, a note about where to park or which entrance is meant, the nearest stop with the walk in minutes — and a way to start the route on their own navigation device. All of that can be delivered without any foreign embed: with your own plain illustration of the surroundings and an ordinary link. A link to a route planner transmits nothing until somebody clicks it. That is precisely the moment the supervisory authorities describe for additional functions (German Data Protection Conference, guidance for providers of telemedia services).
Address as text
Street, number, postcode and town as selectable text rather than an image. Add floor, entrance and doorbell label when several parties share the building. This is the detail people actually copy and forward.
Route link instead of a frame
An ordinary link that opens a route planner with the destination filled in. Nothing happens before the click; after it the person leaves your page deliberately. Two variants — car and public transport — cover almost every case.
Your own surroundings graphic
A plain illustration with the three or four landmarks that matter: main road, junction, car park, entrance. Served from your own domain — and often easier to read than a map section at default zoom.
The same care applies to your own surroundings graphic as to any other image: it needs a descriptive alternative text so the information still arrives without sight, and it should be served in a modern format at a sensible size. What that looks like in detail is covered in the article on image formats and alternative text. If you do not want to give up the interactive map, embed it behind the same click-to-load step described for video in the next section: a preview area with an explanation, a control, and only then the frame loads. What matters is that the release stays a real decision — it has to name where data goes, and it must not be pre-selected. How such a decision is recorded and kept revocable is covered in the article on consent and cookie dialogs.
- Full address as text, selectable, with floor or entrance.
- Phone number as a dialling link and email address as a link.
- One sentence about parking and one about public transport, both with the walk in minutes.
- Two route links: one for the car, one for public transport.
- Your own surroundings graphic as an image with descriptive alternative text.
- Opening hours, or a clear note that appointments are arranged.
- No request to a foreign domain as long as nobody has clicked.
Video: preview image instead of player
An embedded video player is the most expensive embed on the whole list — in data as well as in loading time. The pattern that solves both is called a facade: instead of the player, the page first shows only a static preview image with a play symbol that looks the same but loads nothing. Only the click replaces the facade with the real player. The order of magnitude from the example in the Lighthouse documentation: the facade weighs 3 KB (Chrome for Developers, Lighthouse), while the player loaded on interaction weighs 540 KB (Chrome for Developers, Lighthouse).
In data protection terms the difference is even sharper than in weight. Before the click there is no connection to the video provider: no IP transmission, no cookie, no third-country question. After the click there is a deliberate action — exactly the situation the supervisory authorities describe for additional functions (German Data Protection Conference, guidance for providers of telemedia services). The prerequisite is that the area says, before the click, what is about to happen: which provider, what gets transmitted, and where to read up on it. That notice is not legal boilerplate, it is one normal sentence in normal language.
- Generate the preview image from the video itself and serve it as your own file — do not fetch it from the video provider, or the connection is back.
- Design the area with a play symbol, title and running time so it reads as a player rather than as an error.
- Put a short notice above or below the area: provider, what gets transmitted, link to the privacy policy.
- On click, insert the frame and start playback right away so no second click is needed.
- Remember the decision for the duration of the visit so the same person does not have to release it again on every subpage.
- Check operability: the release area has to be a genuine control with keyboard focus and a descriptive label, not a bare image.
The apparent shortcut
| Variant | Before the click | After the click |
|---|---|---|
| Player embedded directly | Connection to the provider, IP transmitted, player assets load | Playback starts |
| Player behind the consent dialog | Grey area with a consent notice, no connection | Accept first, then load the player, then start |
| Facade with your own preview image | Image from your own domain, no foreign connection | Player loads and starts in one step |
| Video served by you | Your own preview image, no foreign connection | Playback from your own domain, no release needed |
For short clips — thirty seconds of the workshop, a walkthrough, a product note — the fourth variant is particularly worthwhile. A well compressed file in a modern format often weighs less than the player alone, is served from your own domain, and needs neither a release nor a notice. For long videos, an entire media library, or content that is meant to earn reach on a video platform anyway, the facade remains the better route. That the release area has to be keyboard-reachable and labelled is not optional extra polish: it is a control like any other and falls under the requirements described in the article on an accessible business website.
Icons, libraries and the quiet leftovers
Icon packs are the classic among unnoticed embeds. A single line in the page head loads an entire symbol alphabet from a foreign server — for a website that ends up using six pictograms. The replacement is unspectacular: the symbols you need are written as SVG directly into the HTML. That removes not only the foreign connection but also a request, a dependency on the vendor's availability, and the delay until the symbol alphabet has loaded. As a side effect, inline symbols take the colour of the surrounding text and scale with enlarged type.
<!-- Before: the entire symbol pack from a foreign domain -->
<link rel="stylesheet" href="https://cdn.third-party.com/icons/6.5.0/all.css">
<i class="icon icon-phone"></i>
<!-- After: only the symbol needed, inline in the document -->
<svg width="20" height="20" viewBox="0 0 24 24" fill="none"
stroke="currentColor" stroke-width="2" aria-hidden="true" focusable="false">
<path d="M22 16.9v3a2 2 0 0 1-2.2 2 19.8 19.8 0 0 1-8.6-3.1
19.5 19.5 0 0 1-6-6A19.8 19.8 0 0 1 2.1 4.2 2 2 0 0 1 4.1 2h3
a2 2 0 0 1 2 1.7c.1.9.3 1.8.6 2.7a2 2 0 0 1-.5 2.1L8.1 9.6
a16 16 0 0 0 6 6l1.1-1.1a2 2 0 0 1 2.1-.5c.9.3 1.8.5 2.7.6
a2 2 0 0 1 1.7 2z"/>
</svg>Libraries from delivery networks
Carousels, form helpers, animation tools. Download the file once and ship it with your own files. The version then stays stable even if the vendor changes something or shuts the endpoint down.
Review widgets
Star bars that load live and report every page view in the process. Reviews can usually be maintained as plain text on the page instead — stating the source and the period they cover.
Chat and booking windows
Frequently load during the first page build although they are only needed after a click. The same click-to-load step used for video turns this into a deliberate decision rather than a silent transmission.
Form protection
Mechanisms against automated submissions often load from foreign servers. Timing checks, a hidden field and a simple arithmetic question serve the same purpose on small forms without any transmission.
The last find is usually not a service but a corpse: a library an earlier template brought along, a map frame on an old landing page, a counting pixel from a provider you stopped working with years ago. These entries are the best part of the clean-up, because their solution is deletion and nobody has to discuss it. How to keep such legacy out of the site permanently belongs to the topic of regular website maintenance; that every unnecessary foreign embed is also additional attack surface is covered in the article on your own attack surface.
The right moment for the rebuild
The side effect: fewer connections, a calmer page
Every foreign domain costs more than the file it delivers. Before the first byte arrives there is name resolution, connection setup and encryption negotiation — and all of that again for every additional server. On top of that comes an effect the Web Almanac describes well: third-party content pulls in third-party content of its own. The median depth of such inclusion chains is 3.4 (HTTP Archive Web Almanac), and 34 percent (HTTP Archive Web Almanac) of all chains are longer than one link. So in roughly a third of cases an embedded resource drags further ones along that do not appear in your own source at all — and that you therefore will not see if you only search the HTML.
The honest part of the story: a speed gain is likely but not automatic. web.dev explicitly points out that the advantage of self-hosted fonts is less clear cut in practice than in theory and depends on the route and protocol used to deliver your own files (web.dev). Serve those files with a long cache lifetime, modern compression and a current protocol and you come out ahead. Put them on a slow server and you have only moved the problem. The privacy gain, by contrast, materialises either way — and fewer requests are still a gain even when the stopwatch does not show a dramatic jump.
What changes measurably
Order of work and checklist
The order is not arbitrary. First comes what can be replaced without any visible change — that is where the largest effect meets the smallest amount of discussion. Then comes what requires a design decision, because the appearance of the page changes. Last comes what is deleted outright. The following list is the short version of this article and is meant to be worked through in that sequence; every open item is a concrete task with an unambiguous result.
- Network analysis run on at least three types of page, result recorded in a table.
- Test repeated without touching the consent dialog — no foreign domain may be requested before the decision.
- Source searched for
iframe,@import,preconnectanddns-prefetch. - Fonts moved into your own domain, WOFF2 used,
font-display: swapset. - Licence of the typefaces in use checked for self-hosting, result documented.
- Symbol fonts and icon packs replaced with inline graphics.
- Libraries from delivery networks stored locally or removed outright.
- Directions rebuilt: address as text, two route links, your own surroundings graphic.
- Videos switched to a preview image with click-to-load, preview image from your own domain.
- Release areas implemented as operable controls with keyboard focus and a label.
- Privacy policy updated to the new state — what is gone belongs out of it too.
- Network analysis repeated and the result filed next to the first measurement.
What delivery by default takes off your plate
What stands out about this list is how little of it is a question of expertise. Almost every item describes a default setting: where do fonts come from? Where do images live? When does a player load? Anyone who has to answer those questions afresh with every rebuild will eventually answer one of them wrongly — not out of carelessness, but because a copied embed line takes ten seconds and the clean route takes half an hour. So the more interesting question is not how to clean up, but how to keep the same pile from accumulating again within a year.
Fonts and symbols from your own domain
Font files and pictograms are shipped when the site is published, in a modern format and with a display strategy already set. There is no reference to a font service that could be forgotten during removal.
Media live where the page lives
Uploaded images are converted, compressed and served from the same domain as the page itself. That removes the most common quiet leftover — a preview image that comes from the foreign server after all.
Maps and video only after release
External frames load only once somebody deliberately releases them; until then an explanatory area names the provider. The decision applies to the visit and can be revoked.
The difference does not show on publication day but on the fifth change request: when a subpage is added, a video swapped or the typeface changed, the default setting decides whether a foreign connection appears again. In XICflow that default is set to be data-frugal — fonts, symbols and media come from your own domain, maps and videos require a release. Which building blocks are available for that is listed in the overview of features; how a site goes from idea to publication is shown in the process at a glance, and what the result looks like is shown by the example sites.
The short version
Sources and studies
iframe, @import, preconnect and dns-prefetch.