The shell performs variable expansion and the shell performs command substitution but it does not do them recursively:
The result of a variable expansion will not be subjected to any further variable expansion or command substitution.
The result of a command substitution will not be subjected to any further variable expansion or command substitution.
This is a good thing because, if it was done recursively, there would be all manor of unexpected results and security issues.
One solution is to use eval. This is a generally dangerous approach and should be regarded as a last resort.
The safe solution is to rethink what you want. In particular, when do you want hostname evaluated? Should it be evaluated before the site file is created? Or, should it be evaluated when the code is finally run? The latter appears to be what you want.
If that is the case, consider this approach. Put %s in the site file where you want the host name to go:
$ cat site
http://%s/main.html
When you read the site file, use printf to substitute in the host name:
$ mysite=$(printf "$(cat site)" "$(hostname)")
$ echo "$mysite"
http://artur/main.html
With bash, an alternative for the form for the above is:
$ printf -v mysite "$(< site)" "$HOSTNAME"
$ echo "$mysite"
http://artur/main.html
$(cat site)can be replaced with$(< site).