Skip to content

Commit

Permalink
feat: add new link builder (#322)
Browse files Browse the repository at this point in the history
  • Loading branch information
mdanilowicz authored Jul 18, 2023
1 parent a75617f commit b9a2004
Show file tree
Hide file tree
Showing 27 changed files with 105 additions and 45 deletions.
5 changes: 5 additions & 0 deletions .changeset/strong-toes-add.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"vue-demo-store": minor
---

Replace `localePath` with `formatLink`
5 changes: 5 additions & 0 deletions .changeset/wild-bees-laugh.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@shopware-pwa/composables-next": minor
---

Add `formatLink` method to the `useInternationalization` composable
5 changes: 3 additions & 2 deletions apps/docs/src/getting-started/languages.md
Original file line number Diff line number Diff line change
Expand Up @@ -104,15 +104,16 @@ www.example2.com // DE site

## Routing

When you are using _prefix_ domain languages, you have to use `useLocalePath()` composable for building URLs.
When you are using _prefix_ domain languages, you have to use `formatLink()` method from `useInternationalization` composable for building URLs.
The main task of this composable is to add a prefix to URL if needed.

```vue
<script setup lang="ts">
const localePath = useLocalePath();
const { formatLink } = useInternationalization(localePath);
</script>
<template>
<NuxtLink :to="localePath('/account')"> Account</NuxtLink>
<NuxtLink :to="formatLink('/account')"> Account</NuxtLink>
</template>
```

Expand Down
30 changes: 29 additions & 1 deletion packages/composables/src/useInternationalization.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,14 +61,26 @@ export type UseInternationalizationReturn = {
* Current prefix from the context
*/
currentPrefix: Ref<string>;
/**
* Add prefix to the Url
* @param {string | RouteObject} link
*/
formatLink(link: string | RouteObject): string | RouteObject;
};

export type RouteObject = {
path: string;
[key: string]: any;
};

/**
* Composable for internationalization management.
* @public
* @category Context & Language
*/
export function useInternationalization(): UseInternationalizationReturn {
export function useInternationalization(
pathResolver?: Function,
): UseInternationalizationReturn {
const { devStorefrontUrl } = useShopwareContext();
const { apiInstance } = useShopwareContext();

Expand Down Expand Up @@ -114,13 +126,29 @@ export function useInternationalization(): UseInternationalizationReturn {
: url;
}

function formatLink(link: string | RouteObject) {
if (!pathResolver) return link;

if (typeof link === "string") {
return pathResolver(link);
}

if (link.path) {
link.path = pathResolver(link.path);
return link;
}

return link;
}

return {
getAvailableLanguages,
getStorefrontUrl,
changeLanguage,
getLanguageCodeFromId,
getLanguageIdFromCode,
replaceToDevStorefront,
formatLink,
languages: _storeLanguages,
currentLanguage: _storeCurrentLanguage,
currentPrefix: _storeCurrentPrefix,
Expand Down
2 changes: 1 addition & 1 deletion templates/vue-demo-store/app.vue
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ if (languages.value?.elements.length && router.currentRoute.value.name) {
const sessionLanguage = getLanguageCodeFromId(languageIdChain.value);
// If languages are not the same, set one from prefix
if (sessionLanguage !== prefix && sessionLanguage !== getDefaultLocale()) {
if (sessionLanguage !== prefix) {
await changeLanguage(
getLanguageIdFromCode(prefix ? prefix : getDefaultLocale()),
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ const { refreshSessionContext } = useSessionContext();
const { mergeWishlistProducts } = useWishlist();
const { pushSuccess } = useNotifications();
const localePath = useLocalePath();
const { formatLink } = useInternationalization(localePath);
const loginErrors = ref<string[]>([]);
const formData = ref({
Expand All @@ -22,7 +23,7 @@ const formData = ref({
const goToRegister = () => {
emits("close");
router.push(localePath("/register"));
router.push(formatLink("/register"));
};
const invokeLogin = async (): Promise<void> => {
Expand Down
4 changes: 2 additions & 2 deletions templates/vue-demo-store/components/account/AccountMenu.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ const { isLoggedIn, logout, user } = useUser();
const loginModalController = useModal();
const localePath = useLocalePath();
const { formatLink } = useInternationalization(localePath);
const isAccountMenuOpen = ref(false);
async function invokeLogout() {
Expand Down Expand Up @@ -79,7 +79,7 @@ async function invokeLogout() {
>
<NuxtLink
id="user-menu-item-1"
:to="localePath('/account')"
:to="formatLink('/account')"
data-testid="header-my-account-link"
class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 w-full text-left"
tabindex="-1"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ const props = defineProps<{
const { cartItems, totalPrice, isEmpty } = useCart();
const localePath = useLocalePath();
const { formatLink } = useInternationalization(localePath);
</script>

<template>
Expand Down Expand Up @@ -67,15 +68,15 @@ const localePath = useLocalePath();
'bg-gray': isEmpty,
'hover:bg-gray': isEmpty,
}"
:to="localePath(isEmpty ? '' : '/checkout')"
:to="formatLink(isEmpty ? '' : '/checkout')"
data-testid="cart-checkout-link"
>
Checkout
</NuxtLink>

<NuxtLink
class="flex items-center justify-center py-3 text-sm font-medium text-brand-dark"
:to="localePath(`/checkout/cart`)"
:to="formatLink(`/checkout/cart`)"
data-testid="cart-checkout-shopping-cart"
@click="props.controller.close"
>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<script setup lang="ts">
const localePath = useLocalePath();
const { formatLink } = useInternationalization(localePath);
</script>

<template>
Expand All @@ -10,7 +11,7 @@ const localePath = useLocalePath();
</p>
<NuxtLink
class="inline-flex justify-center items-center py-2 px-4 text-base font-medium text-center text-white bg-brand-primary rounded-lg hover:bg-gray-400"
:to="localePath(`/`)"
:to="formatLink(`/`)"
>
{{ $t("backToHomepage") }}
</NuxtLink>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<script setup lang="ts">
const { breadcrumbs } = useBreadcrumbs();
const localePath = useLocalePath();
const { formatLink } = useInternationalization(localePath);
</script>
<template>
<nav
Expand All @@ -10,7 +11,7 @@ const localePath = useLocalePath();
<ol class="inline-flex items-center space-x-1 md:space-x-3">
<li class="inline-flex items-center">
<NuxtLink
:to="localePath(`/`)"
:to="formatLink(`/`)"
class="inline-flex items-center text-sm font-medium text-gray-700 hover:text-gray-900 dark:text-gray-400 dark:hover:text-white"
>
<div class="w-5 h-5 i-carbon-home mr-2" />
Expand All @@ -25,7 +26,7 @@ const localePath = useLocalePath();
>
<NuxtLink
v-if="breadcrumb.path"
:to="localePath(breadcrumb.path)"
:to="formatLink(breadcrumb.path)"
class="inline-flex items-center text-sm font-medium text-gray-700 hover:text-gray-900 dark:text-gray-400 dark:hover:text-white"
>
{{ breadcrumb.name }}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<script setup lang="ts">
const localePath = useLocalePath();
const { formatLink } = useInternationalization(localePath);
</script>

<template>
Expand All @@ -9,7 +10,7 @@ const localePath = useLocalePath();
class="flex justify-between items-center border-b-2 border-gray-100 py-6 md:justify-start md:space-x-10"
>
<div class="flex justify-start lg:w-0 lg:flex-1 space-x-4 md:space-x-0">
<NuxtLink :to="localePath(`/`)">
<NuxtLink :to="formatLink(`/`)">
<span class="sr-only">Shopware</span>
<img
class="h-8 w-auto sm:h-10"
Expand Down
5 changes: 3 additions & 2 deletions templates/vue-demo-store/components/layout/LayoutFooter.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
const { navigationElements } = useNavigation({ type: "footer-navigation" });
const localePath = useLocalePath();
const { formatLink } = useInternationalization(localePath);
const gridColumns = computed<number>(() =>
navigationElements.value
Expand All @@ -22,7 +23,7 @@ const gridColumns = computed<number>(() =>
:class="`grid grid-cols-2 md:grid-cols-${gridColumns}`"
>
<div class="hidden md:block">
<NuxtLink :to="localePath(`/`)">
<NuxtLink :to="formatLink(`/`)">
<span class="sr-only">Shopware</span>
<img class="h-15 w-auto sm:h-15" src="/logo.svg" alt="Logo" />
</NuxtLink>
Expand All @@ -47,7 +48,7 @@ const gridColumns = computed<number>(() =>
? '_blank'
: ''
"
:to="localePath(getCategoryRoute(navigationChild))"
:to="formatLink(getCategoryRoute(navigationChild))"
class="text-base font-normal text-gray-500 hover:text-gray-900"
>
{{ getTranslatedProperty(navigationChild, "name") }}
Expand Down
5 changes: 3 additions & 2 deletions templates/vue-demo-store/components/layout/LayoutHeader.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
const { count } = useCart();
const { count: wishlistCount } = useWishlist();
const localePath = useLocalePath();
const { formatLink } = useInternationalization(localePath);
const sidebarController = useModal();
</script>
Expand All @@ -12,7 +13,7 @@ const sidebarController = useModal();
<div class="flex items-center border-b-2 border-gray-100 py-6 space-x-4">
<div class="flex justify-start items-center min-w-10 lg:min-w-12">
<div class="order-2 lg:order-1 ml-4 lg:ml-0">
<NuxtLink :to="localePath(`/`)">
<NuxtLink :to="formatLink(`/`)">
<span class="sr-only">Shopware</span>
<img
class="h-10 w-10 lg:h-12 lg:w-12"
Expand Down Expand Up @@ -42,7 +43,7 @@ const sidebarController = useModal();
class="group -m-2 p-2 flex items-center relative text-center"
aria-label="wishlist"
data-testid="wishlist-button"
:to="localePath(`/wishlist`)"
:to="formatLink(`/wishlist`)"
>
<div
class="w-7 h-7 i-carbon-favorite text-gray-600 hover:text-brand-primary hover:animate-count-infinite hover:animate-heart-beat"
Expand Down
5 changes: 3 additions & 2 deletions templates/vue-demo-store/components/layout/LayoutSideMenu.vue
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ const { navigationElements } = useNavigation();
const sideMenuController = useSideMenuModal();
const localePath = useLocalePath();
const { formatLink } = useInternationalization(localePath);
const expandedIds = ref<Array<string>>([]);
function isCollapsed(navigationelement: Category): boolean {
Expand Down Expand Up @@ -54,7 +55,7 @@ const toggleCollapse = (navigationElement: Category) => {
class="flex flex-col flex-1 w-full"
>
<NuxtLink
:to="localePath(getCategoryRoute(navigationElement))"
:to="formatLink(getCategoryRoute(navigationElement))"
class="flex items-center px-5 py-3 text-base font-normal text-gray-900 break-all hover:bg-gray-100"
@click="sideMenuController.close"
>
Expand Down Expand Up @@ -104,7 +105,7 @@ const toggleCollapse = (navigationElement: Category) => {
:key="childElement.id"
>
<NuxtLink
:to="localePath(getCategoryRoute(childElement))"
:to="formatLink(getCategoryRoute(childElement))"
class="flex items-center p-3 text-base font-normal text-gray-500 break-all hover:bg-gray-100 pl-11"
@click="sideMenuController.close"
>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ const active = ref(false);
const searchContainer = ref(null);
const searchInput = ref();
const localePath = useLocalePath();
const { formatLink } = useInternationalization(localePath);
watch(active, (value) => {
const { focused } = useFocus(searchInput);
Expand Down Expand Up @@ -101,7 +102,7 @@ watch(enter, (value) => {
<NuxtLink
v-for="product in getProducts.slice(0, displayTotal)"
:key="product.id"
:to="localePath(getProductRoute(product))"
:to="formatLink(getProductRoute(product))"
data-testid="layout-search-suggest-link"
@click="[(active = false), $emit('link-clicked')]"
>
Expand All @@ -121,7 +122,7 @@ watch(enter, (value) => {
<NuxtLink
v-if="getTotal > 0"
data-testid="layout-search-result-box-more-link"
:to="localePath({ path: `/search`, query: { query: typingQuery } })"
:to="formatLink({ path: `/search`, query: { query: typingQuery } })"
@click="[(active = false), $emit('link-clicked')]"
>
{{ $t("search.see") }}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ const currentMenuPosition = ref<string | null>(null);
const menuHtmlElement = ref(null);
const localePath = useLocalePath();
const { formatLink } = useInternationalization(localePath);
onClickOutside(menuHtmlElement, () => (currentMenuPosition.value = null));
</script>
Expand All @@ -33,7 +34,7 @@ onClickOutside(menuHtmlElement, () => (currentMenuPosition.value = null));
? '_blank'
: ''
"
:to="localePath(getCategoryRoute(navigationElement))"
:to="formatLink(getCategoryRoute(navigationElement))"
class="text-base font-medium text-gray-500 hover:text-gray-900 p-2 inline-block"
>
{{ getTranslatedProperty(navigationElement, "name") }}
Expand Down Expand Up @@ -72,7 +73,7 @@ onClickOutside(menuHtmlElement, () => (currentMenuPosition.value = null));
class="relative grid gap-6 bg-white px-3 py-2 sm:gap-6 sm:p-3"
>
<NuxtLink
:to="localePath(getCategoryRoute(childElement))"
:to="formatLink(getCategoryRoute(childElement))"
:target="
childElement.externalLink || childElement.linkNewTab
? '_blank'
Expand Down
7 changes: 4 additions & 3 deletions templates/vue-demo-store/components/product/ProductCard.vue
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ const { pushSuccess, pushError } = useNotifications();
const { t } = useI18n();
const { codeErrorsNotification } = useCartNotification();
const localePath = useLocalePath();
const { formatLink } = useInternationalization(localePath);
const props = withDefaults(
defineProps<{
Expand Down Expand Up @@ -96,7 +97,7 @@ const srcPath = computed(() => {
]"
>
<RouterLink
:to="localePath(getProductRoute(product))"
:to="formatLink(getProductRoute(product))"
class="overflow-hidden"
>
<img
Expand Down Expand Up @@ -154,7 +155,7 @@ const srcPath = computed(() => {
<div class="px-4 pb-4">
<RouterLink
class="line-clamp-2"
:to="localePath(getProductRoute(product))"
:to="formatLink(getProductRoute(product))"
data-testid="product-box-product-name-link"
>
<h5
Expand Down Expand Up @@ -191,7 +192,7 @@ const srcPath = computed(() => {
</button>
<RouterLink
v-else
:to="localePath(getProductRoute(product))"
:to="formatLink(getProductRoute(product))"
class="justify-center py-2 px-3 border border-transparent shadow-sm text-sm font-medium rounded-md text-white bg-black hover:bg-gray-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-gray-500 transform transition duration-400 hover:scale-120"
>
<span data-testid="product-box-product-show-details"> Details </span>
Expand Down
Loading

2 comments on commit b9a2004

@vercel
Copy link

@vercel vercel bot commented on b9a2004 Jul 18, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@vercel
Copy link

@vercel vercel bot commented on b9a2004 Jul 18, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

frontends-demo – ./templates/vue-demo-store

frontends-demo.vercel.app
frontends-demo-git-main-shopware-frontends.vercel.app
frontends-demo-shopware-frontends.vercel.app

Please sign in to comment.