diff --git a/fgs/datatypes.py b/fgs/datatypes.py
index 22783e35427d81e773d3b65ad3f8fb43995a81a5..01c4631d04b679bed43b9f2a5fcea874083893a0 100644
--- a/fgs/datatypes.py
+++ b/fgs/datatypes.py
@@ -337,6 +337,8 @@ class Link:
         self._factories = factories
         self.is_external = False
         self.lang = deflang
+        self.type = None
+        self.alias = None
 
         urlasplit = rawurl.split('#')
 
@@ -364,7 +366,6 @@ class Link:
                 if reftype == "slug":
                     # rawurl: 'slug:some-page:de'
                     self._page = None
-                    # TODO handle link/alias pages
                     self._url = None
                     self.type = reftype
                     self.lang = reflang
@@ -384,6 +385,11 @@ class Link:
     def get_page(self):
         if not self._page:
             self._page = self._factories['page'].get(self.refid, self.lang)
+            # handle link/alias pages
+            if 'link' in self._page.metadata:
+                self.alias = self._page.metadata['link']
+                if self.alias.type == "slug":
+                    self.alias.get_page() # make sure that alias knows if it is an alias
         return self._page
     page = property(get_page, None, None)
 
diff --git a/theme/templates/macros/content_renderer.html b/theme/templates/macros/content_renderer.html
index 9c0d509bfcc3d3e633701c4c07384b9560ca308a..b123c2ee79c4d4a5cd702d1297c8e01a3e030bad 100644
--- a/theme/templates/macros/content_renderer.html
+++ b/theme/templates/macros/content_renderer.html
@@ -54,13 +54,15 @@
 {%- endmacro -%}
 
 {%- macro render_image(link, alt, lang, attr = None, title = None) -%}
-	<img {{ render_attr(attr, lang, extra={"src": link.urlwithanchor, "title": {"value":title, "escape": true}}) }} alt="
-		{%- if alt is string -%}
-			{{ alt|e }}
-		{%- else -%}
-			{{ render_inlines(alt, lang) }}
-		{%- endif -%}
-	">
+	{%- call(resolvedlink, objtype, obj) linkr.resolve(link) -%}
+		<img {{ render_attr(attr, lang, extra={"src": resolvedlink.urlwithanchor, "title": {"value":title, "escape": true}}) }} alt="
+			{%- if alt is string -%}
+				{{ alt|e }}
+			{%- else -%}
+				{{ render_inlines(alt, lang) }}
+			{%- endif -%}
+		">
+	{%- endcall -%}
 {%- endmacro -%}
 
 {%- macro render_blocks_or_inlines(bsois, lang) -%}
diff --git a/theme/templates/macros/link.html b/theme/templates/macros/link.html
index a0e93885ec570ebf54ad71ef2847599cd15b41ca..ac9a323acbfda5e35ce64deb17490ffd03488631 100644
--- a/theme/templates/macros/link.html
+++ b/theme/templates/macros/link.html
@@ -2,30 +2,57 @@
 {%- import 'macros/renderers.html' as renderm with context -%}
 
 
-{%- macro render(link, content, lang, attr = None, title = None) -%}
-	{%- set ns = namespace(relation=None, url=link.urlwithanchor) -%}
-	{%- if link.is_external -%}
-		{%- set ns.relation = "external" -%}
-	{%- else -%}
-		{%- set ns.relation = "internal" -%}
-		{%- set ns.url = [siteurl, ns.url]|join("/") -%}
+{%- macro resolve(link) -%}
+	{%- set ns = namespace(alias=link, objtype=link.type, obj=None) -%}
+
+	{%- if ns.objtype == "tag" -%}
+		{%- set ns.obj = link.tag -%}
+	{%- elif ns.objtype == "slug" -%}
+		{%- set ns.obj = link.page -%}
 	{%- endif -%}
-	{%- set target = config.link_target[ns.relation] -%}
-	<a {{ content_renderer.render_attr(attr, lang, extra_classes=[ns.relation], extra={"href": ns.url, "title": {"value":title, "escape": true}, "target": target}) }}>
-		{%- if content is string or content is none -%}
-			{%- if content is string and content|length -%}
-				{{ renderm.softbreak_span(content) }}
-			{%- else -%}
-				{%- if link.type == "tag" -%}
-					{{ renderm.softbreak_span(link.tag.title) }}
-				{%- elif link.type == "slug" -%}
-					{{ renderm.softbreak_span(link.page.title) }}
-				{%- endif -%}
+
+	{%- if link.alias -%}
+		{%- call(resolvedlink, objtype, obj) resolve(link.alias) -%}
+			{%- set ns.alias = resolvedlink -%}
+
+			{%- if objtype -%}
+				{%- set ns.objtype = objtype -%}
+				{%- set ns.obj = obj -%}
 			{%- endif -%}
+		{%- endcall -%}
+
+	{%- endif -%}
+
+	{{- caller(ns.alias, ns.objtype, ns.obj) -}}
+{%- endmacro -%}
+
+
+{%- macro render(link, content, lang, attr = None, title = None) -%}
+	{%- call(resolvedlink, objtype, obj) resolve(link) -%}
+		{%- set ns = namespace(relation=None, url=resolvedlink.urlwithanchor) -%}
+		{%- if resolvedlink.is_external -%}
+			{%- set ns.relation = "external" -%}
 		{%- else -%}
-			{{ content_renderer.render_blocks_or_inlines(content, lang) }}
+			{%- set ns.relation = "internal" -%}
+			{%- set ns.url = [siteurl, ns.url]|join("/") -%}
 		{%- endif -%}
-	</a>
+		{%- set target = config.link_target[ns.relation] -%}
+		<a {{ content_renderer.render_attr(attr, lang, extra_classes=[ns.relation], extra={"href": ns.url, "title": {"value":title, "escape": true}, "target": target}) }}>
+			{%- if content is string or content is none -%}
+				{%- if content is string and content|length -%}
+					{{ renderm.softbreak_span(content) }}
+				{%- else -%}
+					{%- if objtype == "tag" -%}
+						{{ renderm.softbreak_span(obj.title) }}
+					{%- elif objtype == "slug" -%}
+						{{ renderm.softbreak_span(obj.title) }}
+					{%- endif -%}
+				{%- endif -%}
+			{%- else -%}
+				{{ content_renderer.render_blocks_or_inlines(content, lang) }}
+			{%- endif -%}
+		</a>
+	{%- endcall -%}
 {%- endmacro -%}
 
 {%- macro render_tag(tag, lang) -%}