Create a bilingual page with all of your links - based on Vue 3 + Vite.
See it in action.
Said in advance, the reason for building a potentially static link page as a SPA was simply my personal preference for Vue. It hasn't been the intention to build a lean application but rather experimenting with different concepts and plugins like Pinia and i18n. Consider it as an MVP and keep in mind there might be better alternatives for building a link page.
Some of the provided features and included plugins:
- Bilingualism with Vue I18n
- Light and dark mode - state managed with Pinia
- Link cards with images
- Contact form (server side script or API required)
- Separate views for legal notice and privacy policy - routing with Vue Router
- Bootstrap 5.1 (no plugin)
- Linting with ESLint
- No cookies
Additional features might be added in the future.
Clone the repository:
git clone https://github.com/robinkloeckner/vue3-link-page
Navigate to the project root directory and install the modules:
cd vue3-link-page
npm install
To use the app with minimal effort customize the configuration files under src/config/
and the locales
under src/locales/
.
Contains contact information which are intended be used in multiple times in different places such as the legal notice and privacy policy pages.
If you want to enable the form set enableForm = true
, else false
.
If you want to enable the contact form you need to set enableForm = true
in contact.js
, else false
. Then
add the required information in api.js
. The config file is designed to configure
multiple endpoints. However, in its basic form you only need to adjust the base url of the api baseApiUrl
, the
path
of the endpoint in the postContactForm
object and the header options if needed. Please do not change any key
name.
Creates the i18n instance with options. The default options enable the usage of Vue's Composition API
and <script setup>
syntax. The default locales are English en
and German de
. If you want different locales,
change the corresponding language codes in the options and
the locale resource files in src/locales/
. (more below)
For a full list of options, see the documentation.
Configure the link cards in <main>
and the link icons in <header>
inside the resources
object. Each configuration
object contains the settings
for the header icon and the card of the linked resource. The order of the configuration object defines the order of the
rendered icons and cards.
The following options are available:
Key | Value Type | Necessity | Explanation |
---|---|---|---|
name |
String | required | The name that is shown in the link card. |
url |
String | required | Reference to the external resource. |
icon |
String | required | The name of the component containing the Logo as SVG. The icon is shown in the header and in the link card if enabled (see enableCard option) and if no image is specified in the img option. |
img |
String | optional | Relative path of the image you want to show in the link card (no leading slash required). If specified, the icon specified in icon is only used in the header. enableCard.textOnly must be false in order do display the image. If enableCards: false , the image won`t be rendered. |
enableHeaderIcon |
Boolean | required | true : Icon in the header will be rendered, otherwiste not. |
enableCard |
Object | False | required | If you only want to show a linked resource in the header, set this option false to prevent rendering a link card for the given resource. If you want to render a card, specify an object with testOnly option. |
enableCard.textOnly |
Boolean | optional | If enableCard: true this parameter is required: true will only render a Card with text. false will render the card with either the image or the icon, if set. Otherwise only text will be rendered. |
Examples
Render header icon and card with an image:
website: {
name: "Website",
url: "https://www.robinkloeckner.com/",
icon: "IconGlobe",
img: "img/website.jpg",
enableHeaderIcon: true,
enableCard: {
textOnly: false
}
},
If you omit img
, the card will be rendered with the icon instead.
Render header icon only:
blog: {
name: "Blog",
url: "https://blog.robinkloeckner.com/",
icon: "IconGlobe",
img: "img/website.jpg",
enableHeaderIcon: true,
enableCard: false
},
Specifying img
in this case won't have any effect.
Render text-only card:
setup: {
name: "Setup",
url: "https://blog.robinkloeckner.com/",
enableHeaderIcon: false,
enableCard: {
textOnly: true
}
},
There are separate views for the pages containing the information of the legal notice and the privacy policy. The two
views are located in the src/views/
directory. The content can be set in the locales in src/locales/
as a string
including all HTML elements. This is because some text generators for the legal notice and privacy policy generate HTML
rather than plain text. The boilerplate code works with the v-html
directive and named interpolation from the Vue I18n
plugin in order to use the contact information from the config files.
Change that according to you needs.
This app is build with the intention to provide the content in two different languages. Therefore, providing a second
language is mandatory. The options and the creation of the Vue I18n instance can be found in src/config/i18n.js
,
whereas the locale messages are located in separate files in src/locales/
. Note that some messages contain HTML
elements in their strings and use named interpolation.
For more information on how to work with the plugin check the documentation.
SCSS files are located in src/assets/scss/
. The entry file is main.js
which imports the remaining files. Bootstrap
5.1 is imported here as well following the documentation.
The Bootstrap 5.1 source files are included in the repository (no plugin).
Color variables are defined in custom/variabls.scss
, which are then used to build the theme in custom/themes.scss
.
These are the two main files for customizing the themes of the application. Styles that apply for the complete HTML
document are defined in custom/base.scss
, whereas styles that apply to the Vue app only are defined in App.vue
or
any other Vue component.
Please open an issue for support.