Developer's Guide to Implementing Logo Assets
Published:

Developer's Guide to Implementing Logo Assets

Complete technical guide for developers to integrate Logo Foundry assets into their projects efficiently

Quick Implementation Overview

Different tools export different folder layouts. The standalone Favicon Generator supplies files at the ZIP root, including favicon.ico, favicon-32x32.png, apple-touch-icon.png, site.webmanifest and integration-guide.html. The server upload workflow organizes image files under icons/ and social/, and code under snippets/.

Use the downloadable favicon example to follow this guide without an account. Extract the ZIP before copying files; a link to the ZIP cannot act as an icon URL.

For the following example, copy the favicon PNGs, ICO and Apple Touch PNG into your website's public/icons/ directory. Put the standalone manifest at public/site.webmanifest. These locations map to /icons/... and /site.webmanifest on a conventional static deployment.

If you move files into icons/, update every icon src in the manifest to the new public URL. Relative manifest paths resolve relative to the manifest URL, not the HTML page. For a subpath deployment, include the actual base path in the public URLs.

Basic HTML Implementation

Map the downloaded files to public URLs before adding declarations.

Essential Meta Tags

<link rel="icon" href="/icons/favicon.ico">
<link rel="icon" type="image/png" sizes="32x32" href="/icons/favicon-32x32.png">
<link rel="apple-touch-icon" sizes="180x180" href="/icons/apple-touch-icon.png">
<link rel="manifest" href="/site.webmanifest">

These links use the actual standalone export filenames. Add an SVG link only if your chosen workflow supplied an SVG. Do not add Safari pinned-tab, Windows or social-image links merely because they appear in an old checklist: confirm the files exist and that the feature is relevant.

Web App Manifest Configuration

Copy site.webmanifest from the standalone favicon package to the public root and update each image src to its actual location. A path relative to the manifest is not relative to the HTML page. The manifest describes icons and launch settings; it does not implement offline caching. For standard and maskable examples, see the PWA guide.

Framework-Specific Implementation

The examples below use the same exported files. They are manual integration instructions, not additional framework packages generated by LogoFoundry. Except for SvelteKit's asset placeholder, the URLs assume a deployment at the domain root; adapt them for your project's base path.

Next.js Integration

Choose one icon configuration and inspect the final head. File-based metadata can take precedence over metadata configuration.

App Router (Next.js 13+)

Use the metadata configuration below in your app layout, with the images still under public/icons/. Alternatively, use Next.js's app/favicon.ico, app/icon.png and app/apple-icon.png file conventions. Avoid keeping conflicting file-based and metadata-based icons. See Next.js icon conventions and metadata configuration.

import type { Metadata } from 'next';

export const metadata: Metadata = {
  icons: {
    icon: [
      { url: '/icons/favicon.ico' },
      { url: '/icons/favicon-32x32.png', type: 'image/png', sizes: '32x32' },
    ],
    apple: [{ url: '/icons/apple-touch-icon.png', sizes: '180x180' }],
  },
  manifest: '/site.webmanifest',
};

The manifest is an icon and launch configuration file; it does not implement offline caching or prove installability. Native iOS AppIcon.appiconset and Android res/ exports belong in an app project, not your HTML head.

Pages Router (Next.js 12 and below)

The original heading is retained; Pages Router is not restricted to Next.js 12 and earlier. For an existing Pages Router project, keep the files in public/icons/ and add the links with next/head. Put shared declarations in pages/_app.tsx; remove conflicting declarations from individual pages.

import Head from 'next/head';
import type { AppProps } from 'next/app';

export default function App({ Component, pageProps }: AppProps) {
  return (
    <>
      <Head>
        <link rel="icon" href="/icons/favicon.ico" key="favicon" />
        <link rel="apple-touch-icon" href="/icons/apple-touch-icon.png" />
        <link rel="manifest" href="/site.webmanifest" />
      </Head>
      <Component {...pageProps} />
    </>
  );
}

React (Vite/Create React App)

Copy the icons to public/icons/ and the manifest to public/site.webmanifest. Edit the project-root index.html, not a React component or public/index.html. This also applies to a Vue project that uses Vite's HTML entry. See Vite public assets.

<!-- Inside the existing index.html head -->
<link rel="icon" href="/icons/favicon.ico">
<link rel="apple-touch-icon" href="/icons/apple-touch-icon.png">
<link rel="manifest" href="/site.webmanifest">

Vite copies public files without hashing their filenames. With a configured base, use the appropriate base-prefixed URLs in both the HTML and manifest. Check the built deployment, including a nested route, rather than assuming a working development-server URL proves the final path.

For a maintained older Create React App project, follow that project’s HTML entry and public-path conventions; do not copy the Vite root-entry rule into it unchanged.

Astro

Place the same files under public/. Add the declarations to the existing <head> in a shared layout such as src/layouts/Layout.astro, so pages that use that layout receive the links. Astro's public-directory documentation explains how these files are copied.

<!-- Inside the shared .astro layout head -->
<link rel="icon" href="/icons/favicon.ico">
<link rel="apple-touch-icon" href="/icons/apple-touch-icon.png">
<link rel="manifest" href="/site.webmanifest">

Avoid adding another copy in every page that already uses the shared layout. For an Astro site deployed under a subpath, include that base path in the public URLs and check manifest references too.

SvelteKit

Use static/icons/ for the images and static/site.webmanifest for the manifest. Add these links inside src/app.html's existing head, retaining %sveltekit.head% and the rest of the template. The SvelteKit project structure documents the asset placeholder.

<link rel="icon" href="%sveltekit.assets%/icons/favicon.ico">
<link rel="apple-touch-icon" href="%sveltekit.assets%/icons/apple-touch-icon.png">
<link rel="manifest" href="%sveltekit.assets%/site.webmanifest">

The placeholder belongs to app.html; do not paste it into the JSON manifest. Set manifest image URLs relative to the manifest's deployed location, or use the actual public base path. Confirm the production adapter serves every file.

Advanced Implementation Techniques

Keep a working icon in the initial HTML before adding optional client-side behavior.

Dynamic Favicon Updates

An application may use a different icon for an unread state. Keep a normal icon in the initial HTML, and change one explicitly managed link after the application state changes. This optional example assumes you created and published both PNG files separately; they are not extra assets in the standard ZIP.

<link id="site-favicon" rel="icon" type="image/png" href="/icons/favicon-32x32.png">
function setUnreadIcon(unread) {
  const icon = document.querySelector('link#site-favicon');
  if (icon) {
    icon.setAttribute('href', unread
      ? '/icons/favicon-unread.png'
      : '/icons/favicon-32x32.png');
  }
}

Use the actual deployment base path. If a framework owns the head, integrate the change with that framework's state/head mechanism so subsequent navigation does not undo it. Avoid repeatedly appending icon links. A dynamic tab icon does not update the installed PWA icon or Google's search favicon. For theme-based artwork, see the dark-mode SVG example.

Dark Mode Favicon Switching

A self-contained SVG can use prefers-color-scheme; separate files are another option when supported. Prepare the actual variants and test the browser’s chosen URL. See the dark-mode example. Runtime tab changes do not update the installed-app or search icon.

Performance Optimization

Inspect the actual network requests and smallest image before adding hints or scripts.

Preloading Critical Assets

Do not preload every icon or claim that preloading a 512px PNG guarantees faster installation. Add a preload only after measuring the relevant page and request.

CDN Implementation

A CDN-hosted icon must return the intended file publicly, with a suitable image content type and the correct URL in the head. Inspect CDN caching separately; multiple icon declarations do not guarantee a fixed fallback order.

Lazy Loading for Non-Critical Icons

A service-worker API check does not tell you which favicon sizes the browser needs. Avoid appending every size dynamically as a general optimization; declare the files needed by actual display contexts.

Security Best Practices

Use artwork you trust and inspect SVG before publishing it. If your site uses a Content Security Policy or a separate asset host, inspect console errors and the policy that applies to the image and manifest requests; avoid weakening a site-wide policy just to hide a broken URL. Public favicon and share-image URLs must return image files without requiring a private account session.

Content Security Policy

Inspect browser console errors and the policies applicable to image and manifest requests. Permit only the asset locations your deployment actually uses, and do not replace a site-wide CSP with a copied partial policy.

Integrity Checking

Do not paste an example checksum into a live declaration or assume it proves favicon integrity. Verify known file checksums in your build or release process and inspect the deployed bytes; any browser integrity mechanism must be supported for the exact resource type in use.

Testing and Validation

Validate files, declarations and actual browser displays as separate steps.

Automated Testing

A DOM assertion only checks the declaration; add real file-response checks to the deployment test. For example, in a test environment with the rendered document:

const icon = document.querySelector('link[rel="icon"]');
if (!icon?.getAttribute('href')) throw new Error('Missing icon URL');
const touch = document.querySelector('link[rel="apple-touch-icon"]');
if (!touch?.getAttribute('href')) throw new Error('Missing Apple Touch URL');

Then request the URLs and verify content types and image dimensions rather than accepting an HTML fallback with status 200.

Browser Compatibility Testing

Creating an SVG element or encoding a WebP canvas does not detect support for that format as a favicon. Test the browser/version and target surface directly, recording which public file was selected.

Troubleshooting Common Issues

Work from the public URL and response toward the design, not the other way round.

Issue 1: Favicon Not Appearing

  1. Request each image URL directly and check HTTP status, content type and dimensions. A 200 response containing your HTML fallback page is still a broken image.
  2. Inspect the rendered HTML head and check for duplicate or theme-generated icon declarations.
  3. Open the deployed manifest and verify that its src URLs return the correct PNGs.
  4. Use Favicon Checker for public files, then inspect the target browser or installed app yourself.
  5. If an old icon remains, compare the declared URL with the current file, clear relevant browser/CDN/service-worker caches and test a fresh browser profile. Changing a query string is a diagnostic, not a guaranteed update mechanism.

Google search display is a separate process. Follow Google's favicon guidance; a correct tag does not guarantee immediate display. Report reproducible export or documentation issues through About and contact.

Issue 2: Wrong Size Displayed

Check the actual file dimensions and the sizes attribute. Avoid duplicate framework declarations and distinguish small browser icons from manifest launcher images.

Issue 3: ICO File Not Loading

Confirm the file is a valid ICO, not a renamed PNG or HTML fallback. Inspect server content types and routing. Do not add duplicate Content-Type headers or long immutable caching to a frequently replaced, unversioned URL.

File Organization

Keep the package layout and its public installation layout distinct.

For a public/-based project, a small directory layout is enough:

public/
  icons/
    favicon.ico
    favicon-16x16.png
    favicon-32x32.png
    apple-touch-icon.png
    android-chrome-192x192.png
    android-chrome-512x512.png
  site.webmanifest

This is an installation layout, not a claim that all tools export the same ZIP. In SvelteKit, use static/ instead of public/. If the manifest is at the root, a relative icons/android-chrome-192x192.png refers to the icon folder; a bare android-chrome-192x192.png does not. Keep icon references and actual filenames together during review.

File Naming Conventions

Use the filenames your package actually contains. If you rename or move a file, update HTML and manifest references together. Native app packages belong in their app project, not the website head.

Build Process Integration

For the frameworks above, use the documented public/static directory first; a second custom copy script can create stale duplicates. After building, check the output or the running production adapter for the icon files and manifest. Ensure an SPA fallback rule does not rewrite missing image requests to index.html, and confirm root and nested URLs use the same intended icon paths.

Webpack Configuration

In a custom Webpack project, copy public icon files as part of the project’s established asset pipeline and check the resulting deployment paths. Do not copy a second directory over the framework’s output or assume the ZIP includes a ready-made Webpack integration.

Vite Configuration

Use Vite’s public directory for unchanged icon and manifest files. Do not add the manifest JSON as an HTML Rollup entry. Check configured base, the built HTML and relative icon URLs inside the manifest.

Logo Foundry Integration Workflow

Select the correct tool, inspect the downloaded package, then integrate and test it.

1. Generate Assets

Use the Favicon Generator for its browser export, or the upload workflow for its server package. Different tools produce different layouts; inspect the result before copying.

2. Implement Code Snippets

<link rel="icon" href="/icons/favicon.ico">
<link rel="icon" type="image/png" sizes="32x32" href="/icons/favicon-32x32.png">
<link rel="apple-touch-icon" sizes="180x180" href="/icons/apple-touch-icon.png">
<link rel="manifest" href="/site.webmanifest">

These links use the actual standalone export filenames. Add an SVG link only if your chosen workflow supplied an SVG. Do not add Safari pinned-tab, Windows or social-image links merely because they appear in an old checklist: confirm the files exist and that the feature is relevant.

3. Update Configurations

Use the metadata configuration below in your app layout, with the images still under public/icons/. Alternatively, use Next.js's app/favicon.ico, app/icon.png and app/apple-icon.png file conventions. Avoid keeping conflicting file-based and metadata-based icons. See Next.js icon conventions and metadata configuration.

import type { Metadata } from 'next';

export const metadata: Metadata = {
  icons: {
    icon: [
      { url: '/icons/favicon.ico' },
      { url: '/icons/favicon-32x32.png', type: 'image/png', sizes: '32x32' },
    ],
    apple: [{ url: '/icons/apple-touch-icon.png', sizes: '180x180' }],
  },
  manifest: '/site.webmanifest',
};

The manifest is an icon and launch configuration file; it does not implement offline caching or prove installability. Native iOS AppIcon.appiconset and Android res/ exports belong in an app project, not your HTML head.

4. Validate Implementation

Treat the upload quality report as image-statistics hints and file checks, not WCAG measurement or platform certification. Check the actual files and target browsers yourself.

Performance Optimization

Review caching independently from artwork and icon declarations.

Caching Strategy

Keep a detailed source file for editing and publish only the formats and sizes needed by the target contexts. Optimize a copy, then compare the 16px and 32px results: a smaller file that loses the symbol's cutout is not an improvement. PNG compression does not have a universal JPEG-style quality percentage.

Serve files with suitable image content types. If you use a CDN or service worker, inspect its cache independently from the browser cache. For versioned assets, update HTML and manifest references in the same release and keep the previous files reachable while old documents are cached. A version query can help identify which response is being served, but does not force every browser or installed app to update its icon.

Do not preload every icon as a general performance rule. First inspect actual network requests and page performance. Adding scripts to repeatedly change the favicon also does not solve a wrong deployment path.

HTTP/2 Push

Do not use the old Express res.push example as a deployment recipe or assume every server supports it. Use the project’s actual delivery stack and measured requests; icon setup does not require server push.

Service Worker Caching

If the project already uses a service worker, inspect which cache serves the icon and manifest. Update the application’s established cache versioning and fetch strategy together. Adding only an install-time cache.addAll does not implement a complete offline or update workflow.

Monitoring and Analytics

Keep implementation checks separate from traffic or engagement claims.

Tracking Icon Performance

Inspect request status and transfer timing in the browser or deployment monitoring you already operate. Triggering a new Image() request does not prove how the browser’s favicon loader behaved; performance.now() by itself is not an elapsed icon-load duration.

A/B Testing Favicons

Compare design variants in previews or controlled browser checks first. Do not rotate the search favicon URL for every visitor or claim a traffic improvement without a valid measurement setup.

Common Implementation Patterns

These are optional client-side examples for a link you manage yourself. Create all referenced image files and use the actual base path. Call hooks/composables in the framework’s component lifecycle; reconcile them with any framework-managed head.

React Hook for Dynamic Favicons

Declare one existing icon link with id="site-favicon". This hook changes it after rendering and restores its previous URL when the effect is cleaned up:

import { useEffect } from 'react';

export function useFavicon(href: string) {
  useEffect(() => {
    const link = document.querySelector<HTMLLinkElement>('link#site-favicon');
    if (!link) return;
    const previous = link.getAttribute('href');
    link.setAttribute('href', href);
    return () => {
      if (previous !== null) link.setAttribute('href', previous);
    };
  }, [href]);
}

Call it inside a component with the URL derived from application state. It does not create notification artwork or change installed/search icons.

Vue.js Composable

The same existing-link pattern can be used inside Vue component setup. The initial DOM lookup runs after mount:

import { onMounted, onBeforeUnmount, watch, type Ref } from 'vue';

export function useFavicon(href: Ref<string>) {
  let link: HTMLLinkElement | null = null;
  let previous: string | null = null;
  onMounted(() => {
    link = document.querySelector<HTMLLinkElement>('link#site-favicon');
    previous = link?.getAttribute('href') ?? null;
    link?.setAttribute('href', href.value);
  });
  watch(href, value => link?.setAttribute('href', value));
  onBeforeUnmount(() => {
    if (link && previous !== null) link.setAttribute('href', previous);
  });
}

Use a real published URL and check navigation behavior if the framework also manages the head.

Deployment Checklist

Check the built deployment at the homepage and a nested route.

Pre-Deploy Validation

Before releasing, open the production build at the homepage and a nested URL. Confirm that the icon and manifest paths work without signing in, the manifest references real files, and the head contains the intended declarations. Test relevant browser tabs, bookmarks and Home Screen installation separately. Keep the original artwork and a copy of the deployed package so a later icon change can be compared or rolled back.

Post-Deploy Testing

Request the deployed icons and manifest without signing in. Inspect the final head and test relevant tabs, bookmarks and Home Screen installation separately. Do not mark unused legacy tile features as a universal requirement.

Maintenance and Updates

Keep editable artwork and a known deployed package for comparison or rollback.

Version Management

Keep a detailed source file for editing and publish only the formats and sizes needed by the target contexts. Optimize a copy, then compare the 16px and 32px results: a smaller file that loses the symbol's cutout is not an improvement. PNG compression does not have a universal JPEG-style quality percentage.

Serve files with suitable image content types. If you use a CDN or service worker, inspect its cache independently from the browser cache. For versioned assets, update HTML and manifest references in the same release and keep the previous files reachable while old documents are cached. A version query can help identify which response is being served, but does not force every browser or installed app to update its icon.

Do not preload every icon as a general performance rule. First inspect actual network requests and page performance. Adding scripts to repeatedly change the favicon also does not solve a wrong deployment path.

Automated Validation

In CI, verify the files this project actually deploys and the paths declared in its HTML and manifest. File existence alone is not enough: request the deployed URLs and inspect their response bodies and dimensions. Do not hard-code nonexistent SVG or platform files as mandatory outputs.

Conclusion

Use the framework’s actual public-file conventions, keep declarations aligned with the downloaded package and verify the deployed result. These steps do not guarantee identical rendering in every browser. Report reproducible export or documentation issues through About and contact.

Newsletter

Join the community

Subscribe to our newsletter for the latest news and updates