How to serve a WebID using Apache’s .htaccess file

Having updated my FOAF profile lately to include my WebID, I had to set up a way to serve the foaf profile based on the type of HTTP request. Meaning that when a browser requests the document as text/html, it gets redirected to a php script which uses some libraries to print a user-friendly version of the profile. Otherwise, if the request is for rdf/xml, the rdf file will be served instead. The configuration example I am presenting here is based on the Best Practice Recipes for Publishing RDF Vocabularies document, with slight modifications made by me. It should be noted that this configuration applies for publishing any foaf profile, using rdf/xml.

In case you were wondering, all these configuration lines go into a .htaccess file which you have to put in the same directory with where you have both rdf and html files. Let’s suppose you have a directory structure which resembles mine:

As you can see, I’m using a dedicated directory for each user, in which I am storing the following files:

  • .htaccess
  • foaf.rdf
  • foaf.php

There are just a few lines which need to be modified in the .htaccess file. First, the RewriteBase directive will contain the directory structure for the specified user (let’s go with user ‘andrei’ for now). Next you have the two rules for the types of request (text/html and rdf/xml). You don’t have to change the lines describing the conditions (unless you serve other types of files than .php or .rdf), only the RewriteRule lines.

Let’s take a closer look at the rule line: RewriteRule ^card$ foaf.php [R=303]

What happens here is that when the server receives a text/html request with the URI:, it uses the representation: ^card$ to replace card with foaf.php (the real file which will output html data) and it responds with the html status code 303 (the correct manner in which to redirect web applications to a new URI). At the end, the URL will look like this:

The other rule is very similar, the only difference being the file to which the user is redirected (i.e. foaf.rdf).

Now all that’s left is to decide on a default rule for your profile. To do this, just copy again one of the two lines containing a rule definition. In my case, I chose to go with rdf/xml by default.

Here are the contents of .htaccess:

# Turn off MultiViews
Options -MultiViews
# Directive to ensure *.rdf files served as appropriate content type,
# if not present in main apache config
AddType "application/rdf+xml" .rdf

# Rewrite engine setup
RewriteEngine On
RewriteBase /people/andrei/

# Rewrite rule to serve HTML content from the vocabulary URI if requested
RewriteCond %{HTTP_ACCEPT} !application/rdf\+xml.*(text/html|application/xhtml\+xml)
RewriteCond %{HTTP_ACCEPT} text/html [OR]

RewriteCond %{HTTP_ACCEPT} application/xhtml\+xml [OR]
RewriteCond %{HTTP_USER_AGENT} ^Mozilla/.*
RewriteRule ^card$ foaf.php [R=303]

# Rewrite rule to serve RDF/XML content from the vocabulary URI if requested
RewriteCond %{HTTP_ACCEPT} application/rdf\+xml
RewriteRule ^card$ foaf.rdf [R=303]

# Choose the default response
# Serve RDF/XML by default
RewriteRule ^card$ foaf.rdf [R=303]


To test the new rules, you simply issue the following commands (under Linux):

  • For rdf/xml: `curl -i -H "Accept: rdf/xml" -L`
  • For text/html: curl -i -H "Accept: text/html" -L


Leave a Reply

Your email address will not be published. Required fields are marked *

* Copy This Password *

* Type Or Paste Password Here *


You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>