# Working with public assets
This section covers serving your application’s static resources such as JavaScript, CSS and images.
Serving a public resource in Play 2.0 is the same as serving any other HTTP request. It uses the same routing as regular resources: using the controller/action path to distribute CSS, JavaScript or image files to the client.
## The public/ folder
By convention, public assets are stored in the `public` folder of your application. This folder is organized as follows:
```
public
└ javascripts
└ stylesheets
└ images
```
If you follow this structure it will be simpler to get started, but nothing stops you to modifying it once you understand how it works.
## How are public assets packaged?
During the build process, the contents of the `public` folder are processed and added to the application classpath. When you package your application, these files are packaged into the application JAR file (under the `public/` path).
## The Assets controller
Play 2.0 comes with a built-in controller to serve public assets. By default, this controller provides caching, ETag, gzip compression and JavaScript minification support.
The controller is available in the default Play JAR as `controllers.Assets`, and defines a single `at` action with two parameters:
```
Assets.at(path: String, file: String)
```
The `path` parameter must be fixed and defines the directory managed by the action. The `file` parameter is usually dynamically extracted from the request path.
Here is the typical mapping of the `Assets` controller in your `conf/routes` file:
```
GET /assets/*file controllers.Assets.at(path="/public", file)
```
Note that we define the `*file` dynamic part that will match the `.*` regular expression. So for example, if you send this request to the server:
```
GET /assets/javascripts/jquery.js
```
The router will invoke the `Assets.at` action with the following parameters:
```
controllers.Assets.at("/public", "javascripts/jquery.js")
```
This action will look-up the file and serve it, if it exists.
Note, if you define asset mappings outside "public," you'll need to tell
sbt about it, e.g. if you want:
```
GET /assets/*file controllers.Assets.at(path="/public", file)
GET /liabilities/*file controllers.Assets.at(path="/foo", file)
```
you should add this to the project settings in `project/Build.scala`:
```
// Add your own project settings here
playAssetsDirectories <+= baseDirectory / "foo"
```
## Reverse routing for public assets
As for any controller mapped in the routes file, a reverse controller is created in `controllers.routes.Assets`. You use this to reverse the URL needed to fetch a public resource. For example, from a template:
```html
```
This will produce the following result:
```html
```
Note that we don’t specify the first `folder` parameter when we reverse the route. This is because our routes file defines a single mapping for the `Assets.at` action, where the `folder` parameter is fixed. So it doesn’t need to be specified explicitly.
However, if you define two mappings for the `Assets.at` action, like this:
```
GET /javascripts/*file controllers.Assets.at(path="/public/javascripts", file)
GET /images/*file controllers.Assets.at(path="/public/images", file)
```
Then you will need to specify both parameters when using the reverse router:
```html
```
## Etag support
The `Assets` controller automatically manages **ETag** HTTP Headers. The ETag value is generated from the resource name and the file’s last modification date. (If the resource file is embedded into a file, the JAR file’s last modification date is used.)
When a web browser makes a request specifying this **Etag**, the server can respond with **304 NotModified**.
## Gzip support
But if a resource with the same name but using a `.gz` suffix is found, the `Assets` controller will serve this one by adding the proper HTTP header:
```
Content-Encoding: gzip
```
## Additional `Cache-Control` directive
Usually, using Etag is enough to have proper caching. However if you want to specify a custom `Cache-Control` header for a particular resource, you can specify it in your `application.conf` file. For example:
```
# Assets configuration
# ~~~~~
"assets.cache./public/stylesheets/bootstrap.min.css"="max-age=3600"
```
## Managed assets
By default play compiles all managed assets that are kept in the ```app/assets``` folder. The compilation process will clean and recompile all managed assets regardless of the change. This is the safest strategy since tracking dependencies can be very tricky with front end technologies.
>Note if you are dealing with a lot of managed assets this strategy can be very slow. For this reason there is a way to recompile only the change file and its supposed dependencies. You can turn on this experimental feature by adding the following to your settings:
```
incrementalAssetsCompilation := true
```
You will learn more about managed assets on the next few pages.
> **Next:** [[Using CoffeeScript | AssetsCoffeeScript]]