I had a hard time finding a good answer on how to add a favicon to a JSP-based web application. Many answers on Stack Overflow solve the problem but lack explanation or steps (not to mention incorrect ones). As software engineers, it’s crucial to understand the why before the how. This is why i wrote this answer
The location for static resources (e.g., images, CSS, JavaScript) depends on your project structure:
Dynamic Web Project in Eclipse:
If you are using Dynamic Web Project in Eclipse (File -> New -> Dynamic Web Project), the folder is /WebContent
.
Maven Project:
If you are using maven-archetype-webapp, the folder is src/main/webapp
.
Within these folders, you can create subdirectories for better organization. For example:
src/main/webapp/favicons/
For a deeper explanation, see this excellent answer by Sanjeev.
Rule of Thumb: Always use paths relative to the application context to ensure your links work correctly, regardless of the deployment environment.
The application context is dynamic and changes depending on where the application is deployed.
fortunatly The pageContext is an implicit object available in JSPs and can be accessed using EL (Expression Language)
<link rel="icon" href="${pageContext.request.contextPath}/images/favicon.ico">
This ensures the link adjusts dynamically to deployment paths. For example:
http://example.com/images/favicon.ico
http://example.com/myapp/images/favicon.ico
For more on this, see this answer by no.good.at.coding.
Browsers cache static resources aggressively, including favicons. If you update the favicon, users may still see the old one. To force the browser to reload the updated favicon, append a query parameter like ?v=1
to the URL:
<link rel="icon" href="${pageContext.request.contextPath}/images/favicon.ico?v=1">
When you update the favicon, simply change the version:
<link rel="icon" href="${pageContext.request.contextPath}/images/favicon.ico?v=2">
Why Does This Work? The browser treats URLs with different query parameters as unique resources.
Since the cache distinguishes resources from one another based on their URLs, the cache will not be reused again if the URL changes when a resource is updated.
source: this MDN article.
For further reading, see this answer by Mark.
To support various devices and resolutions, use a tool like RealFaviconGenerator. It generates a set of favicon files for different devices and screen sizes. Place these files in a folder like /favicons/
within your web root.
src/
└── main/
└── webapp/
├── favicons/
│ ├── apple-touch-icon.png
│ ├── favicon-96x96.png
│ ├── favicon.ico
│ ├── favicon.svg
│ ├── site.webmanifest
│ ├── web-app-manifest-192x192.png
│ └── web-app-manifest-512x512.png
├── index.jsp
└── WEB-INF/
└── web.xml
Include the following in the <head>
section of your JSP file:
<!-- Generated by https://realfavicongenerator.net/ -->
<link rel="icon" type="image/png" href="${pageContext.request.contextPath}/favicons/favicon-96x96.png?v=1" sizes="96x96" />
<link rel="icon" type="image/svg+xml" href="${pageContext.request.contextPath}/favicons/favicon.svg?v=1" />
<link rel="shortcut icon" href="${pageContext.request.contextPath}/favicons/favicon.ico?v=1" />
<link rel="apple-touch-icon" sizes="180x180" href="${pageContext.request.contextPath}/favicons/apple-touch-icon.png?v=1" />
<meta name="apple-mobile-web-app-title" content="BrowserSnitch" />
<link rel="manifest" href="${pageContext.request.contextPath}/favicons/site.webmanifest" />
To successfully add a favicon to your JSP-based web application:
webapp
or WebContent
folder.${pageContext.request.contextPath}
for dynamic linking to resources.?v=1
) to handle caching issues.