Add footer
diff --git a/website-v2/package-lock.json b/website-v2/package-lock.json
index 440a064..30cdd78 100644
--- a/website-v2/package-lock.json
+++ b/website-v2/package-lock.json
@@ -8,13 +8,15 @@
         "@docusaurus/core": "2.4.1",
         "@docusaurus/plugin-client-redirects": "2.4.1",
         "@docusaurus/preset-classic": "2.4.1",
+        "@iconify/icons-akar-icons": "^1.2.8",
+        "@iconify/react": "^3.2.2",
         "clsx": "^1.1.1",
         "docusaurus-plugin-sass": "^0.2.4",
         "react": "^17.0.2",
         "react-dom": "^17.0.2",
+        "react-lazy-load-image-component": "^1.5.4",
         "sass": "^1.63.6"
-      },
-      "devDependencies": {}
+      }
     },
     "node_modules/@algolia/autocomplete-core": {
       "version": "1.9.3",
@@ -2729,6 +2731,30 @@
         "@hapi/hoek": "^9.0.0"
       }
     },
+    "node_modules/@iconify/icons-akar-icons": {
+      "version": "1.2.17",
+      "resolved": "https://registry.npmjs.org/@iconify/icons-akar-icons/-/icons-akar-icons-1.2.17.tgz",
+      "integrity": "sha512-diYjqzofnLrWk5NW+D8FJNBZpyZlu1fAb4gWl2TvelzO6K7iM1Z20eWTh7Fe9QhnVZ9bLkXVhiXN7C/9tWDteQ==",
+      "dependencies": {
+        "@iconify/types": "*"
+      }
+    },
+    "node_modules/@iconify/react": {
+      "version": "3.2.2",
+      "resolved": "https://registry.npmjs.org/@iconify/react/-/react-3.2.2.tgz",
+      "integrity": "sha512-z3+Jno3VcJzgNHsN5mEvYMsgCkOZkydqdIwOxjXh45+i2Vs9RGH68Y52vt39izwFSfuYUXhaW+1u7m7+IhCn/g==",
+      "funding": {
+        "url": "http://github.com/sponsors/cyberalien"
+      },
+      "peerDependencies": {
+        "react": ">=16"
+      }
+    },
+    "node_modules/@iconify/types": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/@iconify/types/-/types-2.0.0.tgz",
+      "integrity": "sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg=="
+    },
     "node_modules/@jest/schemas": {
       "version": "29.4.3",
       "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.4.3.tgz",
@@ -7814,6 +7840,11 @@
       "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz",
       "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag=="
     },
+    "node_modules/lodash.throttle": {
+      "version": "4.1.1",
+      "resolved": "https://registry.npmjs.org/lodash.throttle/-/lodash.throttle-4.1.1.tgz",
+      "integrity": "sha512-wIkUCfVKpVsWo3JSZlc+8MB5it+2AN5W8J7YVMST30UrvcQNZ1Okbj+rbVniijTWE6FGYy4XJq/rHkas8qJMLQ=="
+    },
     "node_modules/lodash.uniq": {
       "version": "4.5.0",
       "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz",
@@ -9731,6 +9762,19 @@
         "react-dom": "^17.0.0 || ^16.3.0 || ^15.5.4"
       }
     },
+    "node_modules/react-lazy-load-image-component": {
+      "version": "1.6.0",
+      "resolved": "https://registry.npmjs.org/react-lazy-load-image-component/-/react-lazy-load-image-component-1.6.0.tgz",
+      "integrity": "sha512-8KFkDTgjh+0+PVbH+cx0AgxLGbdTsxWMnxXzU5HEUztqewk9ufQAu8cstjZhyvtMIPsdMcPZfA0WAa7HtjQbBQ==",
+      "dependencies": {
+        "lodash.debounce": "^4.0.8",
+        "lodash.throttle": "^4.1.1"
+      },
+      "peerDependencies": {
+        "react": "^15.x.x || ^16.x.x || ^17.x.x || ^18.x.x",
+        "react-dom": "^15.x.x || ^16.x.x || ^17.x.x || ^18.x.x"
+      }
+    },
     "node_modules/react-lifecycles-compat": {
       "version": "3.0.4",
       "resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz",
diff --git a/website-v2/package.json b/website-v2/package.json
index f4f8ad1..bb2e274 100644
--- a/website-v2/package.json
+++ b/website-v2/package.json
@@ -16,6 +16,9 @@
     "@docusaurus/core": "2.4.1",
     "@docusaurus/plugin-client-redirects": "2.4.1",
     "@docusaurus/preset-classic": "2.4.1",
+    "@iconify/icons-akar-icons": "^1.2.8",
+    "@iconify/react": "^3.2.2",
+    "react-lazy-load-image-component": "^1.5.4",
     "clsx": "^1.1.1",
     "docusaurus-plugin-sass": "^0.2.4",
     "react": "^17.0.2",
diff --git a/website-v2/src/css/util.scss b/website-v2/src/css/util.scss
new file mode 100644
index 0000000..351cb5a
--- /dev/null
+++ b/website-v2/src/css/util.scss
@@ -0,0 +1,60 @@
+@use "sass:map";
+
+$breakpoints: (
+        xs: 369px,
+        sm: 736px,
+        md: 1025px,
+        lg: 1500px,
+);
+
+// @include respond-above() {}
+@mixin respond-above($breakpoint) {
+  @if map.has-key($breakpoints, $breakpoint) {
+    $breakpoint-value: map.get($breakpoints, $breakpoint);
+
+    @media only screen and (min-width: $breakpoint-value) {
+      @content;
+    }
+  }
+
+  @else {
+    @warn "Invalid #{$breakpoint}.";
+  }
+}
+
+// @include respond-below() {}
+@mixin respond-below($breakpoint) {
+  @if map.has-key($breakpoints, $breakpoint) {
+    $breakpoint-value: map.get($breakpoints, $breakpoint);
+
+    @media only screen and (max-width: ($breakpoint-value - 1)) {
+      @content;
+    }
+  }
+
+  @else {
+    @warn "Invalid #{$breakpoint}.";
+  }
+}
+
+// @include respond-between(sm, md) {}
+@mixin respond-between($lower, $upper) {
+  @if map.has-key($breakpoints, $lower) and map.has-key($breakpoints, $upper) {
+    $lower-breakpoint: map.get($breakpoints, $lower);
+    $upper-breakpoint: map.get($breakpoints, $upper);
+
+    @media only screen and (min-width: $lower-breakpoint) and (max-width: ($upper-breakpoint - 1)) {
+      @content;
+    }
+  }
+
+  @else {
+    @if (map.has-key($breakpoints, $lower) == false) {
+      @warn "Lower breakpoint invalid: #{$lower}.";
+    }
+
+    @if (map.has-key($breakpoints, $upper) == false) {
+      @warn "Upper breakpoint invalid: #{$upper}.";
+    }
+  }
+}
diff --git a/website-v2/src/theme/DocSidebar/index.js b/website-v2/src/theme/DocSidebar/index.tsx
similarity index 99%
rename from website-v2/src/theme/DocSidebar/index.js
rename to website-v2/src/theme/DocSidebar/index.tsx
index e86652b..2e57fd1 100644
--- a/website-v2/src/theme/DocSidebar/index.js
+++ b/website-v2/src/theme/DocSidebar/index.tsx
@@ -5,7 +5,6 @@
 export default function DocSidebarWrapper(props) {
   return (
       <>
-
         <div className="custom-sidebar-version">
           <div className={"custom-sidebar-inner"}><span style={{ "display": "inline-block" }}>Version</span> <DocsVersionDropdownNavbarItem dropdownItemsBefore={[]} dropdownItemsAfter={[]} /></div>
         </div>
diff --git a/website-v2/src/theme/Footer/index.tsx b/website-v2/src/theme/Footer/index.tsx
new file mode 100644
index 0000000..518e81b
--- /dev/null
+++ b/website-v2/src/theme/Footer/index.tsx
@@ -0,0 +1,156 @@
+/* eslint-disable react/prop-types */
+/**
+ * Copyright (c) Facebook, Inc. and its affiliates.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ */
+import type { FC } from 'react';
+import React from 'react';
+import Link from '@docusaurus/Link';
+import useBaseUrl from '@docusaurus/useBaseUrl';
+import { Icon } from '@iconify/react';
+import githubIcon from '@iconify/icons-akar-icons/github-fill';
+import twitterIcon from '@iconify/icons-akar-icons/twitter-fill';
+import linkedInIcon from '@iconify/icons-akar-icons/linkedin-fill';
+import { LazyLoadImage } from 'react-lazy-load-image-component';
+import style from './styles.module.scss';
+
+const footer = {
+  links: [
+    {
+      title: 'ASF',
+      items: [
+        {
+          label: 'Foundation',
+          to: 'https://www.apache.org/',
+        },
+        {
+          label: 'License',
+          to: 'https://www.apache.org/licenses/',
+        },
+        {
+          label: 'Events',
+          to: 'https://www.apache.org/events/',
+        },
+        {
+          label: 'Security',
+          to: 'https://www.apache.org/security/',
+        },
+        {
+          label: 'Sponsorship',
+          to: 'https://www.apache.org/foundation/sponsorship.html',
+        },
+        {
+          label: 'Thanks',
+          to: 'https://www.apache.org/foundation/thanks.html',
+        },
+      ],
+    },
+    {
+      title: 'Community',
+      items: [
+        {
+          icon: githubIcon,
+          label: 'GitHub Issues',
+          to: 'https://github.com/apache/streampipes/issues',
+        },
+        {
+          icon: githubIcon,
+          label: 'Github Discussions',
+          to: 'https://github.com/apache/streampipes/issues',
+        },
+        {
+          icon: twitterIcon,
+          label: 'Twitter',
+          to: 'https://twitter.com/StreamPipes',
+        },
+        {
+          icon: linkedInIcon,
+          label: 'LinkedIn',
+          to: 'https://www.linkedin.com/company/apache-streampipes',
+        },
+      ],
+    },
+    {
+      title: 'More',
+      items: [
+        {
+          label: 'Blog',
+          to: '/blog/',
+          target: '_parent',
+        }, {
+          label: 'Privacy',
+          to: 'https://privacy.apache.org/policies/privacy-policy-public.html',
+          target: '_parent',
+        }
+      ],
+    },
+  ],
+  logo: {
+    alt: 'Apache Software Foundation',
+    src: '/img/asf_logo_wide_small.avif',
+    href: 'https://www.apache.org/',
+  },
+
+  copyright:
+    `Copyright © 2019-${new Date().getFullYear()} The Apache Software Foundation. Apache StreamPipes, Apache, the Apache feather logo, and the Apache StreamPipes project logo are either registered trademarks or trademarks of the Apache Software Foundation.`,
+};
+
+const FooterLink = ({
+                      to, icon, href, label, prependBaseUrlToHref, ...props
+                    }) => {
+  const toUrl = useBaseUrl(to);
+  const normalizedHref = useBaseUrl(href, {
+    forcePrependBaseUrl: true,
+  });
+  const hrefObj = href
+    ? {href: prependBaseUrlToHref ? normalizedHref : href}
+    : {to: toUrl};
+  return (
+    <Link
+      {...hrefObj}
+      {...props}
+    >
+      <Icon icon={icon}/>
+      <span>{label}</span>
+    </Link>
+  );
+};
+
+const Footer: FC = () => {
+  const {copyright, links, logo} = footer;
+
+  if (!footer) {
+    return null;
+  }
+
+  return (
+    <footer className={style.container}>
+      {links && links.length > 0 && (
+        <div className={style.linksRow}>
+          {links.map(({title, items}) => (
+            <div key={title} className={style.linksCol}>
+              <div>{title}</div>
+              <ul>
+                {items.map((v) => (
+                  <li key={v.to} className="footer__item">
+                    <FooterLink {...v} />
+                  </li>
+                ))}
+              </ul>
+            </div>
+          ))}
+        </div>
+      )}
+      <div className={style.copyright}>
+        <Link href={logo.href}>
+          <LazyLoadImage alt={logo.alt} src={logo.src} height="40px" width="231.25px"/>
+        </Link>
+        <div className={style.text}>{copyright}</div>
+      </div>
+    </footer>
+  );
+};
+
+export default Footer;
diff --git a/website-v2/src/theme/Footer/styles.module.scss b/website-v2/src/theme/Footer/styles.module.scss
new file mode 100644
index 0000000..31b76c2
--- /dev/null
+++ b/website-v2/src/theme/Footer/styles.module.scss
@@ -0,0 +1,113 @@
+@import "../../css/util";
+
+$links-color: #707279;
+$margin: 8px;
+
+.container {
+  border-top: 1px solid #cecece;
+  background: #f3f3f3;
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+  padding: 20px 25%;
+  min-width: 50%;
+
+  & .linksRow {
+    display: flex;
+    flex-direction: row;
+    justify-content: space-between;
+
+    & .linksCol {
+      display: flex;
+      flex-direction: column;
+
+      & div {
+        font-weight: bolder;
+        margin-bottom: $margin * 2;
+        margin-left: -0.5px;
+      }
+
+      & ul {
+        padding: 0;
+        margin: 0;
+        list-style-type: none;
+
+        li {
+          line-height: 1.15em;
+          margin-bottom: calc($margin / 2);
+          padding: calc($margin / 4) 0;
+
+          a {
+            display: flex;
+            align-items: center;
+            color: $links-color;
+
+            &:hover {
+              color: var(--ifm-link-color);
+            }
+
+            svg {
+              $size: $margin * 2;
+
+              width: $size;
+              height: $size;
+              margin-right: $margin;
+            }
+
+            span {
+              font-size: 14px;
+              margin-top: 2px;
+            }
+          }
+        }
+      }
+    }
+  }
+
+  @include respond-below(sm) {
+    padding: 0;
+    margin: 4rem 1rem 1.5rem;
+
+    & .linksRow {
+      display: grid;
+      column-gap: 50px;
+      row-gap: 25px;
+      grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
+
+      & .linksCol {
+        margin-bottom: $margin;
+
+        & div {
+          margin-bottom: $margin;
+          margin-left: 0;
+        }
+
+        & ul {
+          li {
+            a {
+              span {
+                font-size: 16px;
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+}
+
+.copyright {
+  text-align: center;
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+  align-items: center;
+  max-width: 680px;
+  font-size: 12px;
+  color: $links-color;
+  margin-top: 2.4rem;
+
+  @include respond-below(sm) {
+    text-align: left;
+  }
+}
diff --git a/website-v2/static/img/asf_logo_wide_small.avif b/website-v2/static/img/asf_logo_wide_small.avif
new file mode 100644
index 0000000..7a35b74
--- /dev/null
+++ b/website-v2/static/img/asf_logo_wide_small.avif
Binary files differ