Overall score is a professional judgement on a 0-100 scale, explained in each area below.
Verified measured directly from your website by our crawler Assessment professional judgement based on the evidence
Executive summary
The bottom line
Technically, tile.sydney is in better shape than most small retail sites we audit: HTTPS with preload-grade HSTS, a clean 404, a working sitemap, correct canonicals on all 20 crawled pages, zero JSON-LD errors and a server responding in under 0.4 seconds. The two things holding it back are weight and measurement. The homepage alone pulls 8,592 KB of imagery across 12 files, with a single 2,115 KB JPEG and a 1,864 KB PNG, and none of the images are in a modern format, which is the single largest drag on a mobile visitor. There is also no Content-Security-Policy header, no og:image on any page, and no analytics or tag manager detected on any of the 20 pages, so nothing you change from here can be measured. Fix the images, add the missing headers and social image, and install analytics; that is a fortnight of work with a disproportionate payoff.
Transport security and headers76
Solid
Judgement based on measured headers: HSTS, X-Frame-Options DENY, nosniff, Referrer-Policy and Permissions-Policy all present; Content-Security-Policy absent; no server version or X-Powered-By exposure.
URLs, redirects and 404 handling92
Strong
Judgement based on: www canonicalised to the apex domain, homepage 200 with no redirect hops, a hard 404 with soft_404 false, no internal redirects recorded and no canonical mismatches across 20 pages.
Crawlability and indexability88
Strong
Judgement based on: sitemap found with 21 URLs against 20 pages crawled, robots.txt present with two narrow disallow rules and a sitemap line, no noindex pages, lang="en-AU" on every page.
Speed and page weight52
Weak
Judgement based on: TTFB 0.371-0.396s and small HTML (10-40 KB) against 8,592 KB of homepage images, a 2,115 KB single JPEG, zero modern-format images and Cache-Control of one hour.
Technical hygiene and metadata68
Developing
Judgement based on: favicon, charset, viewport and correct 2026 copyright present; no manifest, empty og:image on all pages, no Twitter card, and several title tags over 60 characters (up to 81).
Measurement readiness30
Critical
Judgement based on: zero trackers detected on all 20 crawled pages and two forms with an empty action attribute recorded in the crawl.
Headline findings
The homepage loads 8,592 KB of images across 12 files, including a 2,115 KB JPEG (life-hotel-hardrock.jpg) and a 1,864 KB PNG (life-terrazzo.png).
None of the 12 homepage images use a modern format such as WebP or AVIF (modern format count: 0).
The homepage response carried no Content-Security-Policy header, so the browser has no instruction limiting where scripts, styles or frames may load from.
No analytics or tag-manager code was detected on any of the 20 pages crawled, so site traffic and form submissions are currently unmeasured.
Every page carried an empty Open Graph image value and no Twitter card tag, so links shared to social or messaging apps will render without a picture.
Transport security is otherwise strong: HSTS is set to max-age=31536000 with includeSubDomains and preload, X-Frame-Options is DENY, X-Content-Type-Options is nosniff and Referrer-Policy is strict-origin-when-cross-origin.
Cache-Control on the homepage is max-age=3600 (one hour), which is short for a site whose heaviest assets are static images.
What is working
HTTPS is enforced, the www variant resolves to https://tile.sydney/ and is correctly canonicalised, and the homepage returned 200 with no redirect hops.
A missing URL returned a genuine 404 status with a 7,451-byte page, and the crawler classified it as a real 404 rather than a soft 404.
All 20 crawled pages had a correct canonical tag, a viewport tag, a charset declaration, a single H1, a meta description and lang="en-AU"; no noindex, duplicate title, duplicate H1 or thin page was found.
Structured data is extensive and clean: Organization, Store, WebSite, BreadcrumbList, FAQPage with 28 Question/Answer pairs, Article and CollectionPage types, with zero JSON-LD parse errors across the crawl.
Server response is consistently fast: time to first byte ranged from 0.371 to 0.396 seconds across all 20 pages, with HTML between 10 KB and 40 KB, gzip compression on, and only 3 scripts and 2 stylesheets per page.
Biggest opportunity
Compress and convert the homepage imagery. Reducing 8,592 KB of JPEG and PNG files to modern formats at sensible dimensions is the one change that will most improve how the site feels on a Sydney mobile connection, and it needs no redesign or rebuild.
Biggest risk
Nothing is being measured. With no tracking code detected on any of the 20 pages and no captcha or visible action on the two forms, you cannot tell how many people reach the quote cart, how many submit the request-a-quote form, or whether any technical change helps or hurts.
1
HTTPS, Headers and Exposure
Security headers are short instructions the server sends with every page telling the browser what it is allowed to do. They cost nothing to add and they are the cheapest defence a small site has. tile.sydney has most of them right, and one important one missing. This section lists what was measured on the homepage response and what each item means in practice.
Measured response headers on https://tile.sydney
Item
Measured value
Status
HTTP to HTTPS redirect
Enabled; homepage returned 200 with no redirect hops
Good
Strict-Transport-Security (HSTS)
max-age=31536000; includeSubDomains; preload
Good
Content-Security-Policy
Not sent
Missing
X-Frame-Options
DENY
Good
X-Content-Type-Options
nosniff
Good
Referrer-Policy
strict-origin-when-cross-origin
Good
Permissions-Policy
Present
Good
Server header
Apache (no version string)
Acceptable
X-Powered-By
Not sent
Good
Cookies set on homepage
0
Good
Mixed content (HTTP assets on HTTPS pages)
0 across all 20 pages
Good
HighVerified
No Content-Security-Policy header
A Content-Security-Policy (CSP) is a whitelist telling the browser which domains may supply scripts, styles, images and fonts. Without it, if any third-party script or an injected line of code ever appears on a page, the browser will run it without question. On a site that collects names, emails, phone numbers and project details through two forms, that is the header worth adding next.
Evidence The homepage response carried no Content-Security-Policy header, while HSTS, X-Frame-Options, X-Content-Type-Options, Referrer-Policy and Permissions-Policy were all present.
Recommendation Add a CSP in report-only mode first, watch the browser console for a week, then switch it to enforcing. The site loads only 3 scripts, 2 stylesheets and Google Fonts, so the policy is simple to write.
Starter CSP for Apache (add to .htaccess or the vhost config) apache
# Step 1: run this for one week and check the browser console for blocked items
Header always set Content-Security-Policy-Report-Only "default-src 'self'; img-src 'self' data:; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; font-src 'self' https://fonts.gstatic.com; script-src 'self'; frame-ancestors 'none'; base-uri 'self'; form-action 'self'; object-src 'none'"
# Step 2: once nothing legitimate is blocked, swap the header name to enforce it
# Header always set Content-Security-Policy "default-src 'self'; img-src 'self' data:; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; font-src 'self' https://fonts.gstatic.com; script-src 'self'; frame-ancestors 'none'; base-uri 'self'; form-action 'self'; object-src 'none'"
StrengthVerified
HSTS is configured to preload standard
HSTS tells browsers to only ever reach this domain over HTTPS, even if someone types the address without it. The measured value is the full-strength configuration: one year, all subdomains, and the preload flag. This is the setting most small business sites never reach.
Evidence The homepage response sent Strict-Transport-Security with max-age=31536000, includeSubDomains and preload.
Recommendation If the domain is not already on the HSTS preload list, submit it at hstspreload.org. Be aware the includeSubDomains directive means every future subdomain must also serve HTTPS.
StrengthVerified
Minimal stack and plugin exposure
Attackers scan for version numbers and known plugin paths. This site gives them almost nothing to work with: the Server header says only "Apache" with no version, X-Powered-By is absent, and the crawler detected no content management system fingerprint and no plugins.
Evidence The Server header returned "Apache" with no version string, no X-Powered-By header was sent, and the crawl recorded no detected platform stack and no plugins across 20 pages.
Recommendation Keep it that way. If a CMS or plugin is added later, suppress version disclosure in the generator meta tag and headers at the same time.
NoteVerified
No cookies and no third-party trackers on the homepage
Zero cookies were set on the homepage and no tracking scripts were detected anywhere in the crawl. From a privacy and consent angle this is clean and means no cookie banner is currently required. From a business angle it means you are flying blind, which is covered under Hygiene.
Evidence The homepage set 0 cookies, and no tracker or tag-manager code was detected on any of the 20 pages crawled.
Recommendation When you add analytics, choose a configuration that keeps the consent obligation light (anonymised IP, no advertising signals) and update the Privacy Policy's "Cookies & analytics" section to match what is actually installed.
2
Redirects, Canonicals and 404s
Search engines and buyers should reach one version of every page, with no detours. This is the strongest area of the site. The crawl found one canonical address, no redirect hops on the pages it visited, and a properly configured error page.
StrengthVerified
www resolves to the apex domain and is canonicalised
There is only one live address for the site. Someone typing www.tile.sydney ends up on https://tile.sydney/ and the page declares that as its canonical address, so there is no risk of two copies of the site competing with each other.
Evidence The www.tile.sydney variant returned 200 and resolved to https://tile.sydney/, and the crawler recorded it as correctly canonicalised. Plain HTTP requests redirect to HTTPS.
Recommendation No action. Confirm the redirect is a permanent 301 rather than a temporary 302 when the developer is next in the server config.
StrengthVerified
Canonical tags correct on all 20 pages
A canonical tag is the page saying "this is my real address". Every page crawled declared the right one. Combined with no duplicate titles, no duplicate meta descriptions and no duplicate H1s, there is no sign of duplicate content anywhere in the crawled set.
Evidence All 20 crawled pages passed the canonical check, and the crawl recorded no canonical mismatches, no duplicate titles, no duplicate descriptions and no duplicate H1s.
Recommendation No action now. Re-check after any product or filter URLs with query strings (for example sort or look filters on /shop) are made crawlable, as those are where duplicates usually start.
StrengthVerified
Missing URLs return a genuine 404
A soft 404 is when a missing page returns a "200 OK" status with "page not found" text, which confuses search engines into indexing empty pages. This site does it properly: a real 404 status with a small, styled page.
Evidence A probe of a non-existent URL returned HTTP status 404 with a 7,451-byte response, and the crawler classified it as a hard 404 rather than a soft 404.
Recommendation Add three links to the 404 page if they are not already there: Shop tiles, Request a quote, and Contact. A lost visitor should never have to use the back button.
LowVerified
One of two sampled links redirected
The crawler spot-checked two links and found none broken, but one redirected rather than resolving directly. A single redirect is harmless; a pattern of them adds a delay to every click and dilutes internal linking. The sample is too small to draw a conclusion either way.
Evidence The link sample checked 2 links: 0 were broken and 1 redirected. No internal redirects were recorded among the 20 crawled pages.
Recommendation Run a full link crawl (Screaming Frog free tier covers 500 URLs) and update any internal href that points at a redirecting URL so it points at the final address.
One structural note for later: the navigation on every page links to https://tile.sydney/cart, and /cart is blocked in robots.txt. That is the correct instinct for a cart page, but it means every page carries a link search engines are told to ignore. It costs nothing today and is covered in the next section.
3
Sitemap, Robots and Indexability
This section checks whether search engines and AI crawlers can find and read everything worth finding, and are kept out of everything that is not. The setup here is close to correct, with one rule worth tightening and one page count worth reconciling.
21
URLs in sitemap.xml
Measured from https://tile.sydney/sitemap.xml
20
Pages crawled and returning 200
All returned status 200 with no redirect hops
0
Pages with noindex
No page blocks itself from search results
0
Pages missing a viewport tag
All 20 pages declare a mobile viewport
MediumVerified
Sitemap present and referenced from robots.txt
The sitemap is found, lists 21 URLs and is declared in robots.txt, which is exactly how it should be wired. The crawl reached 20 of those pages. The one-page gap is almost certainly /cart, which robots.txt blocks, but a blocked page should not be listed in the sitemap at all because that sends search engines two contradictory instructions.
Evidence The sitemap at https://tile.sydney/sitemap.xml was found and lists 21 URLs; the crawl reached 20 pages. robots.txt disallows /cart and /oldd/ and includes the sitemap line.
Recommendation Open sitemap.xml, confirm which URL is not in the crawled set, and remove any URL that robots.txt blocks. A sitemap should list only pages you want indexed.
MediumVerified
robots.txt disallows /oldd/ - a legacy directory worth retiring
A disallow rule for /oldd/ suggests an older version of the site still exists on the server. Blocking it in robots.txt stops it being crawled but does not stop it being reachable by anyone who guesses the URL, and old files are a common security liability.
Evidence robots.txt contains two disallow rules: /oldd/ and /cart. It does not block the whole site.
Recommendation Ask the developer whether /oldd/ still contains files. If it is a dead copy, archive it off the server and delete it, then remove the robots rule. If it must stay, protect it with server-level authentication rather than a robots rule.
Every page declares lang="en-AU", which tells browsers, screen readers and search engines this is Australian English. No page carries a noindex instruction, so nothing is accidentally hidden from search. There is no second language version, so hreflang tags are not needed and correctly absent.
Evidence All 20 crawled pages declared lang="en-AU"; the crawl recorded zero noindex pages and no alternate-language versions.
Recommendation No action.
4
Speed and Weight
The server side of this site is genuinely fast. The problem is what the server is asked to send. Time to first byte sat between 0.371 and 0.396 seconds across all 20 pages and the HTML is small, but the homepage pulls more than eight megabytes of images. This section separates the two and gives a prioritised plan.
0.379 s
Homepage time to first byte
Range across 20 pages: 0.371 s to 0.396 s
26,281 bytes
Homepage HTML size
Page HTML ranged from 10 KB to 40 KB sitewide
8,592 KB
Homepage image weight
12 images checked on the homepage
3 / 2
Scripts / stylesheets per page
Consistent across all 20 pages; 0 iframes
0 of 12
Images in a modern format
All homepage images are JPEG or PNG
max-age=3600
Cache-Control
One hour; compression is gzip
Largest homepage images (measured)
File
Size
Format
/img/life/life-hotel-hardrock.jpg
2,115 KB
JPEG
/img/life/life-terrazzo.png
1,864 KB
PNG
/img/life/life-resort-ibiza.jpg
1,815 KB
JPEG
/img/life/life-bathroom-marble.jpg
1,081 KB
JPEG
/img/life/life-pool-bali.jpg
603 KB
JPEG
All 12 homepage images
8,592 KB total
JPEG and PNG only
CriticalVerified
Homepage image payload is roughly 330 times the HTML
The homepage HTML is 26 KB and the images are 8,592 KB. A single 2,115 KB JPEG and a 1,864 KB PNG account for nearly half the total. On a phone on mobile data in Sydney, that is the difference between a page that feels instant and one that fills in slowly while the visitor decides whether to wait. For a tile retailer selling on how things look, big beautiful photography is the right instinct; sending it uncompressed is not.
Evidence The homepage loads 12 images totalling 8,592 KB, the largest being life-hotel-hardrock.jpg at 2,115 KB and life-terrazzo.png at 1,864 KB, against a 26,281-byte HTML document.
Recommendation Target under 200 KB per hero image and under 1,500 KB for the whole homepage. Export at the maximum displayed width (2000 px is ample for a full-bleed hero, 1200 px for cards), convert to WebP or AVIF, and retain a JPEG fallback via the picture element.
HighVerified
No images use a modern format, and a photograph is saved as a PNG
PNG is designed for graphics with flat colour and sharp edges, such as logos. Using it for a terrazzo photograph is the most expensive possible choice: life-terrazzo.png is 1,864 KB where the same image as a quality-80 WebP would typically land in the low hundreds of kilobytes. None of the 12 homepage images use WebP or AVIF, both of which every current browser supports.
Evidence Zero of the 12 homepage images were served in a modern format; life-terrazzo.png is a 1,864 KB PNG and the remaining large files are JPEGs.
Recommendation Convert every photographic asset in /img/life/ to WebP (quality 75-80) and serve with a picture element. Never use PNG for a photograph.
Responsive, modern-format image markup to replace a heavy hero html
Eleven of the twelve homepage images are set to load lazily, meaning the browser only fetches them as the visitor scrolls towards them. Leaving one image eager is the right pattern if that image is the hero at the top of the page. This is already well handled; it just cannot rescue files this large.
Evidence 11 of 12 homepage images carry a lazy-loading attribute, and every image across the crawl had alt text (missing alt count: 0 on all pages).
Recommendation Keep the top hero eager and add fetchpriority="high" to it, so the browser prioritises the one image the visitor actually sees first.
MediumVerified
Cache lifetime of one hour is short for static assets
Cache-Control tells the visitor's browser how long it may reuse a file instead of downloading it again. One hour means a returning visitor re-downloads images that have not changed in months. Hashed or versioned filenames let you cache them for a year safely.
Evidence The homepage response carried Cache-Control: max-age=3600 (one hour). Compression is gzip.
Recommendation Keep a short cache on HTML, but set images, CSS and fonts to one year with immutable. Also enable Brotli compression alongside gzip on Apache, which typically shaves a further 15 to 20 per cent off text assets.
Apache cache and Brotli configuration apache
<IfModule mod_expires.c>
ExpiresActive On
ExpiresByType image/jpeg "access plus 1 year"
ExpiresByType image/png "access plus 1 year"
ExpiresByType image/webp "access plus 1 year"
ExpiresByType image/avif "access plus 1 year"
ExpiresByType text/css "access plus 1 year"
ExpiresByType application/javascript "access plus 1 year"
ExpiresByType text/html "access plus 1 hour"
</IfModule>
<IfModule mod_headers.c>
<FilesMatch "\.(jpg|jpeg|png|webp|avif|css|js|woff2)$">
Header set Cache-Control "public, max-age=31536000, immutable"
</FilesMatch>
</IfModule>
<IfModule mod_brotli.c>
AddOutputFilterByType BROTLI_COMPRESS text/html text/css application/javascript image/svg+xml application/json
</IfModule>
Prioritised performance plan
1. Re-export the five largest homepage images at display size and convert to WebP or AVIF. This alone should remove several megabytes from the homepage.
2. Replace life-terrazzo.png with a WebP or JPEG; a photograph should never be a PNG.
3. Add width and height attributes to every image so the layout does not shift while images load.
4. Add fetchpriority="high" to the single eager hero image and keep the other 11 lazy.
5. Extend Cache-Control on images, CSS and fonts to one year with immutable, keeping HTML at one hour.
6. Enable Brotli compression alongside the existing gzip.
7. Self-host the Archivo and IBM Plex Mono fonts as woff2 with font-display: swap, removing the extra connection to Google Fonts.
8. Once the above is done, run Google PageSpeed Insights on the homepage and a category page to get a measured mobile score and Core Web Vitals baseline. None were captured in this crawl.
5
Hygiene
Hygiene items are the small, cheap details that either quietly help or quietly embarrass. Most are right here: favicon, charset, viewport and a copyright year that matches the current year. Three are not, and one of them affects every link anyone ever shares.
Quick wins, ranked by effort
Item
Measured state
Fix
Effort
Open Graph image
Empty on all 20 pages; no Twitter card tag
Create one 1200x630 og:image and add og:image plus twitter:card to the template
Low
Web app manifest
Absent on all 20 pages
Add a manifest.json with name, icons and theme colour
Low
Copyright year
2026, matching the current year
No action
None
Favicon
Present on all 20 pages
No action
None
Charset and viewport
Declared on all 20 pages
No action
None
Iframes
0 across all 20 pages
No action; note there is no map embed on /contact
None
Form spam protection
Honeypot field (_honey) present on both forms; no captcha
Keep the honeypot, add an invisible captcha or rate limit if spam appears
Low
Form action attribute
Both forms recorded with an empty action value
Confirm with the developer that submissions actually reach an inbox
Low
Analytics
No tracking code detected on any of the 20 pages
Install analytics and configure a form-submission event
Medium
Title tag length
Six titles exceed 60 characters, the longest at 81
Rewrite the over-length titles; see examples below
Low
Meta description length
Several exceed 155 characters, the longest at 249
Trim to 120-155 characters so they display in full
Low
HighVerified
No Open Graph image on any page
When someone shares a tile.sydney link in a WhatsApp group with their builder, pastes it into a Pinterest board or posts it to Instagram, the preview will show text on a blank card. For a business selling on how surfaces look, that is the worst possible first impression of a link. Every page has og:title and og:description; only the image is missing.
Evidence All 20 crawled pages returned an empty Open Graph image value, and no page carried a Twitter card tag, although og:title and og:description were present throughout.
Recommendation Produce one branded 1200x630 default image, plus a specific image for each of the five category pages and four journal articles, and add og:image, og:image:width, og:image:height and twitter:card to the page template.
Social preview tags to add to the head template html
The site has a quote cart, a 20-field request-a-quote form and an 8-field contact form, and no way to count how many people use them. You cannot know whether a technical fix helped, which category page sends the most quote requests, or where people abandon the form.
Evidence No analytics or tag-manager code was detected on any of the 20 pages crawled. The request-a-quote form has 20 fields with 2 required; the contact form has 8 fields with 4 required.
Recommendation Install a privacy-friendly analytics package or Google Analytics 4, set events for add-to-quote-cart, quote form submit and contact form submit, and connect Google Search Console. Update the Privacy Policy's "Cookies & analytics" section at the same time.
MediumVerified
Two forms, no captcha, honeypot only
Both forms include a hidden _honey field, which is a honeypot: a field invisible to humans that crude bots fill in, letting the server discard the submission. It is a sensible first line of defence and it avoids making real customers solve puzzles. It will not stop a targeted bot. The 20-field quote form with only 2 required fields is well designed for completion, but its empty action attribute is worth verifying.
Evidence Both /request-a-quote and /contact record a _honey field and no captcha, and both forms were captured with an empty action attribute.
Recommendation Confirm submissions are actually arriving by sending a live test from a phone on mobile data. Keep the honeypot, add server-side rate limiting, and only add an invisible captcha if spam becomes a real problem.
Homepage title tag: 81 characters trimmed to 51
Before
tile.sydney - Designer Tiles in Sydney | Marble-look, Timber-look, Pool & Outdoor [81]
After
Designer Tiles Sydney | Marble, Timber & Pool Looks [51]
Homepage meta description: 182 characters trimmed to 129
Before
Sydney's designer tile destination - marble-look, timber-look, terrazzo, stone and pool mosaics. Browse 35 designer ranges, add to your quote and we'll send pricing and availability. [182]
After
Sydney designer tile catalogue - marble-look, timber-look, terrazzo, stone and pool mosaics. Add tiles to your quote for pricing. [129]
Outdoor category title: 79 characters trimmed to 52
Before
Outdoor & Alfresco Tiles in Sydney - 20mm Pavers & Grip Porcelain | tile.sydney [79]
Ranked by impact, then effort. Owner tells you who can do it without outside help.
1
Cut the homepage image payload from 8,592 KB to under 1,500 KB
Verified
Impact: highEffort: mediumOwner: web developer
Why: The homepage serves 12 images totalling 8,592 KB, including a 2,115 KB JPEG and a 1,864 KB PNG, against 26 KB of HTML. This is the single heaviest drag on the mobile experience.
How: Re-export each image at the maximum width it is actually displayed at (2000 px for full-bleed, 1200 px for cards), convert to WebP at quality 75-80 with an AVIF source where practical, and replace the img tags with picture elements carrying width and height attributes.
Evidence The homepage loads 12 images totalling 8,592 KB; the largest are life-hotel-hardrock.jpg at 2,115 KB, life-terrazzo.png at 1,864 KB and life-resort-ibiza.jpg at 1,815 KB.
2
Install analytics and track quote-form submissions
Verified
Impact: highEffort: mediumOwner: specialist
Why: No tracking code was detected on any of the 20 pages, so there is no record of visits, of quote cart activity, or of how many people complete the 20-field quote form.
How: Install Google Analytics 4 or a privacy-friendly alternative sitewide, define events for add-to-quote-cart, quote submit and contact submit, verify the property in Google Search Console, and update the Privacy Policy's "Cookies & analytics" wording to match.
Evidence The crawl detected zero trackers across all 20 pages; the site operates a quote cart, a 20-field quote form and an 8-field contact form.
3
Add an Open Graph image and Twitter card to the page template
Verified
Impact: highEffort: lowOwner: web developer
Why: Every one of the 20 crawled pages has an empty og:image value and no Twitter card tag, so shared links show no picture on social, messaging apps or Pinterest.
How: Create one branded 1200x630 default image plus dedicated images for the five category pages and four journal articles, then add og:image, og:image:width, og:image:height, og:image:alt and twitter:card to the head template.
Evidence All 20 pages returned an empty Open Graph image value and no Twitter card tag, while og:title and og:description were present.
4
Convert life-terrazzo.png away from PNG
Verified
Impact: highEffort: lowOwner: web developer
Why: A 1,864 KB photographic image is stored as a PNG, a format meant for flat-colour graphics, making it several times larger than it needs to be.
How: Re-export the terrazzo photograph as WebP at quality 78 with a JPEG fallback, at the width it is actually displayed.
Evidence life-terrazzo.png is 1,864 KB and typed image/png; none of the 12 homepage images use a modern format.
5
Add a Content-Security-Policy header
Verified
Impact: mediumEffort: lowOwner: web developer
Why: The homepage response carried no Content-Security-Policy, so the browser has no whitelist restricting where scripts, styles, fonts or frames may load from on a site that collects personal details through two forms.
How: Deploy the starter policy in report-only mode via .htaccess, review the browser console for a week, then switch to the enforcing header name.
Evidence No Content-Security-Policy header was returned on the homepage, although HSTS, X-Frame-Options, nosniff, Referrer-Policy and Permissions-Policy were all present.
6
Extend cache lifetimes and enable Brotli
Verified
Impact: mediumEffort: lowOwner: web developer
Why: Cache-Control is set to max-age=3600, so returning visitors re-download unchanged images and stylesheets after an hour. Only gzip compression is in use.
How: Apply a one-year immutable cache to images, CSS, JS and woff2 files while keeping HTML at one hour, and enable mod_brotli alongside the existing gzip on the Apache server.
Evidence The homepage returned Cache-Control: max-age=3600 and gzip compression.
7
Trim the over-length title tags and meta descriptions
Verified
Impact: mediumEffort: lowOwner: in-house
Why: Six page titles exceed 60 characters, the longest at 81 on the homepage, and several descriptions exceed 155 characters, the longest at 249 on /timber-look-tiles, so they will be cut off in search results.
How: Rewrite the affected titles to 50-60 characters and descriptions to 120-155, leading with the search term and the location, using the three examples in the Hygiene section as the pattern.
Evidence Measured lengths include an 81-character homepage title, a 249-character description on /timber-look-tiles and a 239-character description on /marble-look-tiles.
8
Verify both forms actually deliver
Verified
Impact: highEffort: lowOwner: in-house
Why: Both the contact and request-a-quote forms were recorded with an empty action attribute, which means submission is handled by script. If that script fails, enquiries disappear silently and nobody finds out.
How: Submit a live test from a phone on mobile data and from a desktop browser, confirm the email arrives, and add an autoresponder so the customer also receives confirmation.
Evidence Both /contact and /request-a-quote record forms with an empty action value; the contact form has 8 fields with 4 required, the quote form 20 fields with 2 required.
9
Resolve the sitemap and robots.txt conflict
Verified
Impact: mediumEffort: lowOwner: web developer
Why: The sitemap lists 21 URLs while 20 were crawled, and robots.txt blocks /cart, which is linked from the navigation on every page. Listing a blocked URL in a sitemap sends search engines contradictory instructions.
How: Open sitemap.xml, identify the URL not in the crawled set, and remove any URL that robots.txt disallows. Add rel="nofollow" to the cart link in the navigation if you want to keep crawlers away from it entirely.
Evidence The sitemap lists 21 URLs against 20 pages crawled; robots.txt disallows /cart and /oldd/; every page links to https://tile.sydney/cart.
10
Retire or protect the /oldd/ directory
Verified
Impact: mediumEffort: lowOwner: web developer
Why: robots.txt disallows /oldd/, which suggests a legacy copy of the site still sits on the server. Robots rules stop crawling but do not stop access, and stale files are a common point of compromise.
How: Ask the developer to confirm what is in /oldd/. Archive it locally, delete it from the server, and remove the robots rule. If it must remain, put it behind HTTP authentication.
Evidence robots.txt contains a Disallow rule for /oldd/.
11
Self-host the two web fonts
Verified
Impact: mediumEffort: mediumOwner: web developer
Why: The site loads Archivo and IBM Plex Mono from Google Fonts, which adds a connection to a third-party domain before text can render and complicates the Content-Security-Policy.
How: Download the woff2 files, serve them from /fonts/ with a one-year cache, add font-display: swap, preload the primary weight, and remove the Google Fonts link.
Evidence The crawl recorded Archivo and IBM Plex Mono loaded via Google Fonts.
12
Add a web app manifest
Verified
Impact: lowEffort: lowOwner: web developer
Why: No manifest was found on any of the 20 pages, so the site has no defined name, icon set or theme colour when saved to a phone home screen.
How: Create /manifest.json with name, short_name, a 192 px and 512 px icon, background and theme colours matching the palette (#f1efe9 and #16130e), and link it from the head template.
Evidence All 20 crawled pages were recorded without a web app manifest.
13
Fix the heading level jump on /shop
Verified
Impact: lowEffort: lowOwner: web developer
Why: The /shop page records two heading-level jumps, meaning heading levels skip a step. Screen readers use headings to navigate, and skipped levels make the structure harder to follow.
How: Review the heading order on /shop so it runs H1, then H2, then H3 without skipping, and apply the same check to the single jump recorded on the other pages.
Evidence The /shop page records 2 heading jumps; the other crawled pages record 1 each.
14
Add useful links to the 404 page
Verified
Impact: lowEffort: lowOwner: web developer
Why: The 404 page returns correctly but is only 7,451 bytes, which suggests a minimal page. A lost visitor with a tile project should be routed onwards, not left at a dead end.
How: Add three prominent links to the 404 template: Shop tiles, Request a quote and Contact, plus the site search or the look filters if available.
Evidence A probe of a non-existent URL returned a 404 status with a 7,451-byte response and was classified as a hard 404.
15
Establish a PageSpeed baseline after the image work
Verified
Impact: mediumEffort: lowOwner: in-house
Why: No Google PageSpeed Insights or Core Web Vitals measurements were captured in this crawl, so the current mobile score is unknown and improvements cannot be quantified.
How: Once the image conversions and caching changes are live, run PageSpeed Insights on the homepage, /bathroom-tiles and /request-a-quote for both mobile and desktop, and record the scores and Core Web Vitals in a simple spreadsheet each quarter.
Evidence The evidence pack contains no PageSpeed Insights data; only server-side timings (TTFB 0.371-0.396 s) were measured.
90-day execution roadmap
Days 1-14
Stop the bleeding: weight, measurement and the missing social image
Re-export and convert the five largest homepage images to WebP or AVIF, targeting under 1,500 KB total for the homepage.
Replace life-terrazzo.png (1,864 KB) with a compressed WebP.
Create the 1200x630 default og:image and add the Open Graph and Twitter card tags to the head template.
Install analytics with events for quote cart adds, quote form submit and contact form submit; verify in Google Search Console.
Send live test submissions through both forms from a phone and a desktop and confirm delivery.
Days 15-45
Server configuration, caching and metadata tidy-up
Deploy the Content-Security-Policy in report-only mode, review for a week, then enforce it.
Apply one-year immutable caching to images, CSS, JS and fonts; enable Brotli alongside gzip.
Rewrite the six over-length title tags and the over-length meta descriptions to the character targets.
Reconcile sitemap.xml with robots.txt and remove any blocked URL from the sitemap.
Confirm what is in /oldd/ and either delete it or put it behind authentication.
Self-host Archivo and IBM Plex Mono as woff2 with font-display: swap.
Days 46-90
Measure, verify and lock in the gains
Run PageSpeed Insights on the homepage, /bathroom-tiles and /request-a-quote for mobile and desktop and record the baseline scores and Core Web Vitals.
Run a full link crawl to confirm no internal link points at a redirecting URL, and fix any that do.
Add a manifest.json and matching icon set, and add Shop, Quote and Contact links to the 404 page.
Review the first 30 days of analytics: which category pages send the most quote requests, and where the 20-field form is abandoned.
Decide consciously whether to publish a phone number, given no tel: link appears anywhere on the site.
Fix the heading level jumps on /shop and audit the remaining pages for the same issue.
Resource gap analysis
Capability
Status
Note
Image optimisation and asset production
Missing
Photography is present and well chosen, but 8,592 KB of homepage images with zero modern-format files shows no compression step exists in the publishing process.
Web development (server configuration)
Partial
Whoever configured HSTS with preload, X-Frame-Options DENY and a hard 404 clearly knows what they are doing; the missing CSP and one-hour cache suggest the job was left unfinished.
Schema and technical SEO
Have
Twelve-plus schema.org types in use across the site including a 28-question FAQPage, with zero JSON-LD parse errors. This is a genuine strength.
Analytics and measurement setup
Missing
No tracking code on any of the 20 pages. Nothing in this report can be validated until this is in place.
Copywriting
Have
Substantial, well-structured copy: 2,206 words on /faq, around 900-1,300 on each category and journal page, readability scores between 39.9 and 67.6. Only the meta lengths need trimming.
Design and social asset creation
Partial
The site has a coherent palette and type pairing, but no Open Graph image exists, so no one has produced share-card assets.
Form and lead-handling operations
Partial
Two well-built forms with honeypot protection exist, but with no captcha, no visible action target and no analytics event, the handling of submissions is unverified.
Ongoing technical monitoring
Missing
No evidence of uptime, broken-link or performance monitoring. A quarterly crawl and a PageSpeed check would catch regressions early.
Limitations of this report
This report is based on a single crawl of the public pages listed in the evidence appendix, on the date shown on the cover. It does not include analytics, advertising, sales or customer data, and it cannot see printed or physical brand materials.
Glossary
TTFB (time to first byte)
How long the server takes to start sending a page after the browser asks for it. Measured here at 0.371 to 0.396 seconds, which is fast.
Content-Security-Policy (CSP)
A header listing which domains are allowed to supply scripts, styles, images and fonts. Without it a browser will run any code that appears on the page.
HSTS
Strict-Transport-Security. Tells browsers to only ever connect to this site over HTTPS, even if someone types the address without it.
Canonical tag
A line in the page code saying "this is my official address", used to stop search engines treating two URLs as two separate copies of the same page.
Soft 404
A page that says "not found" but returns a success status code, which misleads search engines into indexing empty pages. This site correctly avoids it.
WebP and AVIF
Modern image formats that store photographs at a fraction of the file size of JPEG or PNG, supported by every current browser.
Lazy loading
Telling the browser to fetch an image only when the visitor scrolls near it, rather than all at once on page load.
Cache-Control
A header telling the visitor's browser how long it may reuse a downloaded file instead of fetching it again.
Open Graph image (og:image)
The picture that appears when a link is shared on social media or in a messaging app. Currently empty on every page of this site.
Honeypot field
A hidden form field invisible to people but filled in by crude spam bots, letting the server discard those submissions automatically.
Appendix: Verified Evidence
Everything in this appendix was measured directly from tile.sydney on 17 September 2026 by the Markus Marketing crawler (20 pages, 22.7 seconds). It is reproducible and independent of the analysis above.
Site-level checks
HTTP redirects to HTTPS
Yes
www / non-www canonicalised
Yes (www.tile.sydney -> HTTP 200)
Unknown URL returns 404
Yes (probe returned HTTP 404)
robots.txt present
Yes Disallow: /oldd/, /cart
XML sitemap found
Yes 21 URLs listed
llms.txt present
not checked
Internal links verified
not recorded
Favicon / web manifest on homepage
Yes / No
Homepage time to first byte
0.379 s (total 0.379 s, HTML 26 KB, compression: gzip)