Compare commits
10 Commits
1b8c390ba6
...
5a1d8073b5
Author | SHA1 | Date |
---|---|---|
Rafael González Vázquez | 5a1d8073b5 | |
Rafael González | a73a6220f5 | |
Rafael González | d7845ad4aa | |
Rafael González | 3492009582 | |
Rafael González | 4fafa3a172 | |
Rafael González | b8697e601f | |
Rafael González | c53ad08818 | |
Rafael González | 04578e06be | |
Rafael González | 8980fe3986 | |
Rafael González | 21cc79ea7a |
|
@ -19,3 +19,4 @@ yarn-error.log*
|
||||||
|
|
||||||
# Local Netlify folder
|
# Local Netlify folder
|
||||||
.netlify
|
.netlify
|
||||||
|
.astro
|
||||||
|
|
|
@ -1,16 +1,20 @@
|
||||||
|
import { defineConfig } from "astro/config";
|
||||||
import tailwind from "@astrojs/tailwind";
|
import tailwind from "@astrojs/tailwind";
|
||||||
import svelte from "@astrojs/svelte";
|
import svelte from "@astrojs/svelte";
|
||||||
import { defineConfig } from "astro/config";
|
|
||||||
import sitemap from "@astrojs/sitemap";
|
import sitemap from "@astrojs/sitemap";
|
||||||
|
|
||||||
import mdx from "@astrojs/mdx";
|
import mdx from "@astrojs/mdx";
|
||||||
|
import partytown from "@astrojs/partytown";
|
||||||
|
|
||||||
// https://astro.build/config
|
// https://astro.build/config
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
site: "https://rafa.page",
|
site: "https://rafa.page/",
|
||||||
integrations: [tailwind({
|
integrations: [tailwind({
|
||||||
config: {
|
config: {
|
||||||
applyBaseStyles: false,
|
applyBaseStyles: false
|
||||||
}
|
}
|
||||||
}), svelte(), sitemap(), mdx()]
|
}), svelte(), sitemap(), mdx(), partytown({
|
||||||
|
config: {
|
||||||
|
forward: ["dataLayer.push"]
|
||||||
|
}
|
||||||
|
})]
|
||||||
});
|
});
|
|
@ -0,0 +1,8 @@
|
||||||
|
[dev]
|
||||||
|
framework = "astro"
|
||||||
|
|
||||||
|
[[redirects]]
|
||||||
|
from="/blog/optimizeing-shopify-theme"
|
||||||
|
to="/blog/optimizeing-shopify-theme-1"
|
||||||
|
status=301
|
||||||
|
force = true
|
23
package.json
23
package.json
|
@ -9,11 +9,22 @@
|
||||||
"preview": "astro preview"
|
"preview": "astro preview"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@astrojs/mdx": "^0.9.0",
|
"@astrojs/mdx": "^0.17.0",
|
||||||
"@astrojs/sitemap": "^1.0.0",
|
"@astrojs/sitemap": "^1.0.1",
|
||||||
"@astrojs/svelte": "^1.0.0",
|
"@astrojs/svelte": "^2.0.2",
|
||||||
"@astrojs/tailwind": "^1.0.0",
|
"@astrojs/tailwind": "^3.0.1",
|
||||||
"astro": "^1.0.3",
|
"@notionhq/client": "^2.2.0",
|
||||||
"svelte": "^3.49.0"
|
"astro": "^2.0.14",
|
||||||
|
"marked": "^4.1.0",
|
||||||
|
"notion-to-md": "^2.5.5",
|
||||||
|
"postcss": "^8.4.21",
|
||||||
|
"rollup": "^3.17.2",
|
||||||
|
"svelte": "^3.49.0",
|
||||||
|
"tailwindcss": "^3.2.7",
|
||||||
|
"typescript": "^4.9.5",
|
||||||
|
"vite": "^4.1.4"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@astrojs/partytown": "^1.2.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
4079
pnpm-lock.yaml
4079
pnpm-lock.yaml
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,166 @@
|
||||||
|
---
|
||||||
|
layout: ../../layouts/main.astro
|
||||||
|
date: 2022-08-18
|
||||||
|
title: Optimizing performance of an old Shopify Theme (Part 1)
|
||||||
|
description:
|
||||||
|
Some tips and recommendations for optimizing and boosting performance of an
|
||||||
|
old Shopify theme.
|
||||||
|
exerpt:
|
||||||
|
Some tips and recommendations for optimizing and boosting performance of an
|
||||||
|
old Shopify theme.
|
||||||
|
image: https://images.unsplash.com/photo-1506818144585-74b29c980d4b?crop=entropy&cs=tinysrgb&fm=jpg&ixid=MnwzNTMzMzl8MHwxfGFsbHx8fHx8fHx8fDE2NjA3OTI2NjA&ixlib=rb-1.2.1&q=80&w=350&ar=16:9&fit=crop
|
||||||
|
---
|
||||||
|
|
||||||
|
# Optimizing an old Shopify Theme (Part 1)
|
||||||
|
|
||||||
|
<img
|
||||||
|
alt="Optimizing an old Shopify Theme"
|
||||||
|
class="cover"
|
||||||
|
src="https://images.unsplash.com/photo-1506818144585-74b29c980d4b?crop=entropy&cs=tinysrgb&fm=jpg&ixid=MnwzNTMzMzl8MHwxfGFsbHx8fHx8fHx8fDE2NjA3OTI2NjA&ixlib=rb-1.2.1&q=80&w=300&ar=5:2&fit=crop"
|
||||||
|
srcset="https://images.unsplash.com/photo-1506818144585-74b29c980d4b?crop=entropy&cs=tinysrgb&fm=jpg&ixid=MnwzNTMzMzl8MHwxfGFsbHx8fHx8fHx8fDE2NjA3OTI2NjA&ixlib=rb-1.2.1&q=80&w=300&ar=5:2&fit=crop 300w,
|
||||||
|
https://images.unsplash.com/photo-1506818144585-74b29c980d4b?crop=entropy&cs=tinysrgb&fm=jpg&ixid=MnwzNTMzMzl8MHwxfGFsbHx8fHx8fHx8fDE2NjA3OTI2NjA&ixlib=rb-1.2.1&q=80&w=500&ar=5:2&fit=crop 500w,
|
||||||
|
https://images.unsplash.com/photo-1506818144585-74b29c980d4b?crop=entropy&cs=tinysrgb&fm=jpg&ixid=MnwzNTMzMzl8MHwxfGFsbHx8fHx8fHx8fDE2NjA3OTI2NjA&ixlib=rb-1.2.1&q=80&w=800&ar=5:2&fit=crop 800w,
|
||||||
|
https://images.unsplash.com/photo-1506818144585-74b29c980d4b?crop=entropy&cs=tinysrgb&fm=jpg&ixid=MnwzNTMzMzl8MHwxfGFsbHx8fHx8fHx8fDE2NjA3OTI2NjA&ixlib=rb-1.2.1&q=80&w=1024&ar=5:2&fit=crop 1024w"
|
||||||
|
sizes="(max-width: 310px) 300px,
|
||||||
|
(max-width: 510px) 500px,
|
||||||
|
(max-width: 810px) 800px,
|
||||||
|
1024px"
|
||||||
|
/>
|
||||||
|
|
||||||
|
## Some tips and recommendations for optimizing and boosting performance of an old Shopify theme.
|
||||||
|
|
||||||
|
At <a href="https://acromatico.dev" target="_blank">Acromático Development</a>
|
||||||
|
we are always helping our clients optimize their Shopify stores, not only the UX
|
||||||
|
and UI, but also the performance and speed of the site. Optimizing a Shopify
|
||||||
|
theme is not a simple task, it has been a long learning path that continues
|
||||||
|
evolving and improving as we test and try new methodologies.
|
||||||
|
|
||||||
|
In this first blog post I want to share some of the things I've learned during
|
||||||
|
this process, that way maybe I can help other jump through some of the hard
|
||||||
|
parts of successfully optimizing a Shopify theme.
|
||||||
|
|
||||||
|
### Web Vitals and Shopify Themes
|
||||||
|
|
||||||
|
If you are reading this post it is because you’ve probably been trying to find
|
||||||
|
ways to optimize your store theme or a client theme. Shopify shows an average
|
||||||
|
score for the theme by running three pages through Google Lightspeed daily,
|
||||||
|
these three pages are the home page, product page and collection page.
|
||||||
|
|
||||||
|
If you run these pages via pagespeed.web.dev you’ll notice that the score is
|
||||||
|
given by the result of some Google indicators called Web Vitals, the most
|
||||||
|
important Web Vitals are:
|
||||||
|
|
||||||
|
1. **Largest Contentful Paint (LCP):** Is an important, user-centric metric for
|
||||||
|
measuring perceived load speed because it marks the point in the page load
|
||||||
|
timeline when the page's main content has likely loaded—a fast LCP helps
|
||||||
|
reassure the user that the page is useful.
|
||||||
|
|
||||||
|
[Philip Walton. “Largest Contentful Paint” web.dev, Aug 17, 2022.](https://web.dev/i18n/en/lcp/)
|
||||||
|
|
||||||
|
2. **Cumulative Layout Shift (CLS):** Is a measure of the largest burst of
|
||||||
|
layout shift scores for every unexpected layout shift that occurs during the
|
||||||
|
entire lifespan of a page.
|
||||||
|
|
||||||
|
[Philip Walton. “Cumulative Layout Shiftt” web.dev, Aug 17, 2022.](https://web.dev/i18n/en/cls/)
|
||||||
|
|
||||||
|
3. **First Contentful Paint (FCP):** Is an important, user-centric metric for
|
||||||
|
measuring perceived load speed because it marks the first point in the page
|
||||||
|
load timeline where the user can see anything on the screen—a fast FCP helps
|
||||||
|
reassure the user that something is happening.
|
||||||
|
|
||||||
|
[Philip Walton. “First Contentful Paint” web.dev, Aug 17, 2022.](https://web.dev/i18n/en/fcp/)
|
||||||
|
|
||||||
|
4. **Time to First Bite (TTFB):** Is a foundational metric for measuring
|
||||||
|
connection setup time and web server responsiveness in both the lab and the
|
||||||
|
field. It helps identify when a web server is too slow to respond to
|
||||||
|
requests. In the case of navigation requests—that is, requests for an HTML
|
||||||
|
document—it precedes every other meaningful loading performance metric.
|
||||||
|
|
||||||
|
[Jeremy Wagner. “Time to First Byte” web.dev, Jul 26, 2022.](https://web.dev/ttfb/)
|
||||||
|
|
||||||
|
Some of these metrics can be optimized by making changes in the theme code, some
|
||||||
|
others like TTFB have to do with the server, how fast it renders and sends the
|
||||||
|
initial HTML to the client.
|
||||||
|
|
||||||
|
### Initial Analysis
|
||||||
|
|
||||||
|
Let's start by (in a really broad sense) diferenciating the optimizations that
|
||||||
|
can be done on a Site. We started by separating them in two main areas:
|
||||||
|
|
||||||
|
1. **Optimizing the Server:** Changes that have to do with where you are hosting
|
||||||
|
the page, things like having a fast and reliable CDN, having all the correct
|
||||||
|
catching policies, how fast the server responds, how near to the end user the
|
||||||
|
server is located, etc. This part is nearly imposible to optimize for a
|
||||||
|
Shopify theme since all this part is controlled by Shopify itself.
|
||||||
|
|
||||||
|
As well the amount of Liquid code the server has to render can affect the
|
||||||
|
speed of response of the server, if there's one thing to take care of in this
|
||||||
|
section is the amount of complicated liquid code you are using in your theme.
|
||||||
|
|
||||||
|
2. **Optimizing the Code:** Changes that have to be done on the code of the
|
||||||
|
theme, here's where most of our efforts will be focused. Things like
|
||||||
|
preconnecting to 3rd party servers, preloading assets, removing unused code,
|
||||||
|
optimizing images and orchestating CSS and JavaScript loading times are the
|
||||||
|
things we are going to focus on this section.
|
||||||
|
|
||||||
|
### Optimizing the Code
|
||||||
|
|
||||||
|
I know there are many ways to aproach the optimization of the differents parts
|
||||||
|
of the code, but this is the process I follow, I hope that it makes sense for
|
||||||
|
the mayority of the cases. For this example I will use one of our client's
|
||||||
|
themes (we have previus authorisation to use this theme as an example), the
|
||||||
|
store is called <a href="https://lycklig.com.mx" target="_blank">Lycklig Party
|
||||||
|
Shop</a> and they sell party supplies. They have been in Shopify since 2016 and
|
||||||
|
the theme has been the same sinse the start of the store.
|
||||||
|
|
||||||
|
#### Running the first control tests
|
||||||
|
|
||||||
|
I use two tools to measure the progress that was achieved with the optimization.
|
||||||
|
Google Page Speed Insights and Web Page Test. Both tools are great, Google Page
|
||||||
|
Speed Insights is required since one of the main goals of optimizing a Shopify
|
||||||
|
store is to rank better in Google searches by having better Web Vitals. Web Page
|
||||||
|
Test is a professional tool for those looking to have a deeper look into
|
||||||
|
optimizing a site.
|
||||||
|
|
||||||
|
Webpage Test Report:
|
||||||
|
[Report](https://www.webpagetest.org/result/220819_BiDc6R_B5K/).
|
||||||
|
|
||||||
|
PageSpeed Insights Report:
|
||||||
|
|
||||||
|
<div class="image__container">
|
||||||
|
<img
|
||||||
|
alt="Lycklig Not Optimized Page Speed Insights Report"
|
||||||
|
style="aspect-ratio: 968/895;"
|
||||||
|
src="https://res.cloudinary.com/acromatico-development/image/upload/c_scale,f_auto,w_300/v1660926662/Rafa%20Blog/lycklig-initial-test_jz8jly.png"
|
||||||
|
srcset="https://res.cloudinary.com/acromatico-development/image/upload/c_scale,f_auto,w_300/v1660926662/Rafa%20Blog/lycklig-initial-test_jz8jly.png 300w,
|
||||||
|
https://res.cloudinary.com/acromatico-development/image/upload/c_scale,f_auto,w_500/v1660926662/Rafa%20Blog/lycklig-initial-test_jz8jly.png 500w,
|
||||||
|
https://res.cloudinary.com/acromatico-development/image/upload/c_scale,f_auto,w_760/v1660926662/Rafa%20Blog/lycklig-initial-test_jz8jly.png 760w,
|
||||||
|
https://res.cloudinary.com/acromatico-development/image/upload/c_scale,f_auto,w_968/v1660926662/Rafa%20Blog/lycklig-initial-test_jz8jly.png 968w"
|
||||||
|
sizes="(max-width: 310px) 300px,
|
||||||
|
(max-width: 510px) 500px,
|
||||||
|
(max-width: 768px) 760px,
|
||||||
|
(max-width: 1024px) 500px,
|
||||||
|
968px"
|
||||||
|
/>
|
||||||
|
<small>Lycklig Not Optimized Page Speed Insights Report</small>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
We can see in both cases the theme is not as badly optimized, by looking at the
|
||||||
|
main Web Vitals we can see that the main areas of opportunity are the LCP and
|
||||||
|
CLS, as mentioned before this has to do mostly with all the heavy assets the
|
||||||
|
site has to download and render or execute, as well the CLS has to do with the
|
||||||
|
way the page renderes eather the images or dynamic stuff loaded with JavaScript.
|
||||||
|
|
||||||
|
Most Shopify themes have the same or similar problems and the main area where
|
||||||
|
the templates suffer is the LCP and CLS. Some others have bad FCP nad TTFB
|
||||||
|
because of the bad ussage of liquid when building the theme, there is too much
|
||||||
|
liquid that takes long to render in the server and the usage of legacy liquid
|
||||||
|
code like `{% include 'name_of_file' %}` instead of
|
||||||
|
`{% render 'name_of_file' %}` slow down the initial response time.
|
||||||
|
|
||||||
|
Shopify has a CDN layer that catches the pages, but the catching policy can not
|
||||||
|
be too long since theres a lot of dynamic content in an e-commerce site.
|
||||||
|
|
||||||
|
This is Part 1 of these blog series, if you want to learn abot the practical
|
||||||
|
steps to optimize a Shopify theme read
|
||||||
|
[part 2](/blog/optimizeing-shopify-theme-2) of this blog entry.
|
|
@ -1,7 +1,7 @@
|
||||||
---
|
---
|
||||||
layout: ../../layouts/main.astro
|
layout: ../../layouts/main.astro
|
||||||
date: 2022-08-18
|
date: 2022-08-18
|
||||||
title: Optimizing performance of an old Shopify Theme
|
title: Optimizing performance of an old Shopify Theme (Part 2)
|
||||||
description:
|
description:
|
||||||
Some tips and recommendations for optimizing and boosting performance of an
|
Some tips and recommendations for optimizing and boosting performance of an
|
||||||
old Shopify theme.
|
old Shopify theme.
|
||||||
|
@ -11,7 +11,7 @@ exerpt:
|
||||||
image: https://images.unsplash.com/photo-1506818144585-74b29c980d4b?crop=entropy&cs=tinysrgb&fm=jpg&ixid=MnwzNTMzMzl8MHwxfGFsbHx8fHx8fHx8fDE2NjA3OTI2NjA&ixlib=rb-1.2.1&q=80&w=350&ar=16:9&fit=crop
|
image: https://images.unsplash.com/photo-1506818144585-74b29c980d4b?crop=entropy&cs=tinysrgb&fm=jpg&ixid=MnwzNTMzMzl8MHwxfGFsbHx8fHx8fHx8fDE2NjA3OTI2NjA&ixlib=rb-1.2.1&q=80&w=350&ar=16:9&fit=crop
|
||||||
---
|
---
|
||||||
|
|
||||||
# Optimizing an old Shopify Theme
|
# Optimizing an old Shopify Theme (Part 2)
|
||||||
|
|
||||||
<img
|
<img
|
||||||
alt="Optimizing an old Shopify Theme"
|
alt="Optimizing an old Shopify Theme"
|
||||||
|
@ -30,71 +30,14 @@ image: https://images.unsplash.com/photo-1506818144585-74b29c980d4b?crop=entropy
|
||||||
## Some tips and recommendations for optimizing and boosting performance of an old Shopify theme.
|
## Some tips and recommendations for optimizing and boosting performance of an old Shopify theme.
|
||||||
|
|
||||||
At <a href="https://acromatico.dev" target="_blank">Acromático Development</a>
|
At <a href="https://acromatico.dev" target="_blank">Acromático Development</a>
|
||||||
we are allways helping our clients optimize their Shopify stores, not only the
|
we are always helping our clients optimize their Shopify stores, not only the UX
|
||||||
UX and UI, but also the performance and speed of the site. Optimizing a Shopify
|
and UI, but also the performance and speed of the site. Optimizing a Shopify
|
||||||
theme is not a simple task, it has been a long learning path that continues
|
theme is not a simple task, it has been a long learning path that continues
|
||||||
evolving and improving as we test and try new methodologies.
|
evolving and improving as we test and try new methodologies.
|
||||||
|
|
||||||
In this first blog post I want to share some of the things I've learned during
|
This is a continuation of the Optimizing an old Shopify Theme series, if you
|
||||||
this process, that way maybe I can help other jump through some of the hard
|
want to read about the initial analysis done to know what to look for in a
|
||||||
parts of successfully optimizing a Shopify theme.
|
theme, check out the [part 1](/blog/optimizeing-shopify-theme-1) of this series.
|
||||||
|
|
||||||
### Initial Analysis
|
|
||||||
|
|
||||||
Let's start by (in a really broad sense) diferenciating the optimizations that
|
|
||||||
can be done on a Site. We started by separating them in two main areas:
|
|
||||||
|
|
||||||
1. **Optimizing the Server:** Changes that have to do with where you are hosting
|
|
||||||
the page, things like having a fast and reliable CDN, having all the correct
|
|
||||||
catching policies, how fast the server responds, how near to the end user the
|
|
||||||
server is located, etc. This part is nearly imposible to optimize for a
|
|
||||||
Shopify theme since all this part is controlled by Shopify itself.
|
|
||||||
2. **Optimizing the Code:** Changes that have to be done on the code of the
|
|
||||||
theme, here's where most of our efforts will be focused. Things like
|
|
||||||
preconnecting to 3rd party servers, preloading assets, removing unused code,
|
|
||||||
optimizing images and orchestating CSS and JavaScript loading times are the
|
|
||||||
things we are going to focus on this section.
|
|
||||||
|
|
||||||
### Optimizing the Code
|
|
||||||
|
|
||||||
I know there are many ways to aproach the optimization the differents parts of
|
|
||||||
the code, but this is the process I follow, hope that it makes sense for the
|
|
||||||
mayority of the cases. For this example I will use one of our client's themes
|
|
||||||
(we have previus authorisation to use this theme as an example), the store is
|
|
||||||
calles <a href="https://lycklig.com.mx" target="_blank">Lycklig Party Shop</a>
|
|
||||||
and they sell party supplies. They have been in Shopify since 2016 and the theme
|
|
||||||
has been the same sinse the start of the store.
|
|
||||||
|
|
||||||
#### Running the first control tests
|
|
||||||
|
|
||||||
I use two tools to measure the progress that was achieved with the optimization.
|
|
||||||
Google Page Speed Insights and Web Page Test. Both tools are great, Google Page
|
|
||||||
Speed Insights is required since one of the main goals of optimizing a Shopify
|
|
||||||
store is to rank better in Google searches. Web Page Test is a professional tool
|
|
||||||
for those looking to optimize in depth their site.
|
|
||||||
|
|
||||||
Webpage Test Report:
|
|
||||||
[Report](https://www.webpagetest.org/result/220819_BiDc6R_B5K/).
|
|
||||||
|
|
||||||
PageSpeed Insights Report:
|
|
||||||
|
|
||||||
<div class="image__container">
|
|
||||||
<img
|
|
||||||
alt="Lycklig Not Optimized Page Speed Insights Report"
|
|
||||||
style="aspect-ratio: 968/895;"
|
|
||||||
src="https://res.cloudinary.com/acromatico-development/image/upload/c_scale,f_auto,w_300/v1660926662/Rafa%20Blog/lycklig-initial-test_jz8jly.png"
|
|
||||||
srcset="https://res.cloudinary.com/acromatico-development/image/upload/c_scale,f_auto,w_300/v1660926662/Rafa%20Blog/lycklig-initial-test_jz8jly.png 300w,
|
|
||||||
https://res.cloudinary.com/acromatico-development/image/upload/c_scale,f_auto,w_500/v1660926662/Rafa%20Blog/lycklig-initial-test_jz8jly.png 500w,
|
|
||||||
https://res.cloudinary.com/acromatico-development/image/upload/c_scale,f_auto,w_760/v1660926662/Rafa%20Blog/lycklig-initial-test_jz8jly.png 760w,
|
|
||||||
https://res.cloudinary.com/acromatico-development/image/upload/c_scale,f_auto,w_968/v1660926662/Rafa%20Blog/lycklig-initial-test_jz8jly.png 968w"
|
|
||||||
sizes="(max-width: 310px) 300px,
|
|
||||||
(max-width: 510px) 500px,
|
|
||||||
(max-width: 768px) 760px,
|
|
||||||
(max-width: 1024px) 500px,
|
|
||||||
968px"
|
|
||||||
/>
|
|
||||||
<small>Lycklig Not Optimized Page Speed Insights Report</small>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
#### Preconnecting to 3rd party servers and preloading known assets
|
#### Preconnecting to 3rd party servers and preloading known assets
|
||||||
|
|
||||||
|
@ -160,20 +103,20 @@ them by total time to load we can see the next result:
|
||||||
|
|
||||||
<div class="image__container">
|
<div class="image__container">
|
||||||
<img
|
<img
|
||||||
alt="Lycklig Not Optimized Page Speed Insights Report"
|
alt="Lycklig JS Download"
|
||||||
style="aspect-ratio: 968/895;"
|
style="aspect-ratio: 4/3;"
|
||||||
src="https://res.cloudinary.com/acromatico-development/image/upload/c_scale,f_auto,w_300/v1660926662/Rafa%20Blog/lycklig-initial-test_jz8jly.png"
|
src="https://res.cloudinary.com/acromatico-development/image/upload/c_scale,f_auto,w_300/v1661395344/Rafa%20Blog/lycklig-js-download_siplp5.png"
|
||||||
srcset="https://res.cloudinary.com/acromatico-development/image/upload/c_scale,f_auto,w_300/v1660926662/Rafa%20Blog/lycklig-initial-test_jz8jly.png 300w,
|
srcset="https://res.cloudinary.com/acromatico-development/image/upload/c_scale,f_auto,w_300/v1661395344/Rafa%20Blog/lycklig-js-download_siplp5.png 300w,
|
||||||
https://res.cloudinary.com/acromatico-development/image/upload/c_scale,f_auto,w_500/v1660926662/Rafa%20Blog/lycklig-initial-test_jz8jly.png 500w,
|
https://res.cloudinary.com/acromatico-development/image/upload/c_scale,f_auto,w_500/v1661395344/Rafa%20Blog/lycklig-js-download_siplp5.png 500w,
|
||||||
https://res.cloudinary.com/acromatico-development/image/upload/c_scale,f_auto,w_760/v1660926662/Rafa%20Blog/lycklig-initial-test_jz8jly.png 760w,
|
https://res.cloudinary.com/acromatico-development/image/upload/c_scale,f_auto,w_760/v1661395344/Rafa%20Blog/lycklig-js-download_siplp5.png 760w,
|
||||||
https://res.cloudinary.com/acromatico-development/image/upload/c_scale,f_auto,w_968/v1660926662/Rafa%20Blog/lycklig-initial-test_jz8jly.png 968w"
|
https://res.cloudinary.com/acromatico-development/image/upload/c_scale,f_auto,w_968/v1661395344/Rafa%20Blog/lycklig-js-download_siplp5.png 968w"
|
||||||
sizes="(max-width: 310px) 300px,
|
sizes="(max-width: 310px) 300px,
|
||||||
(max-width: 510px) 500px,
|
(max-width: 510px) 500px,
|
||||||
(max-width: 768px) 760px,
|
(max-width: 768px) 760px,
|
||||||
(max-width: 1024px) 500px,
|
(max-width: 1024px) 500px,
|
||||||
968px"
|
968px"
|
||||||
/>
|
/>
|
||||||
<small>Lycklig Not Optimized Page Speed Insights Report</small>
|
<small>Lycklig JS Downloaded by Theme</small>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
There are 5 super slow scripts:
|
There are 5 super slow scripts:
|
||||||
|
@ -186,31 +129,115 @@ There are 5 super slow scripts:
|
||||||
- https://cdn.shopify.com/s/trekkie.storefront.ebdc6f6e0c97d8f5d6a7dac9bc6ab298fff7cf1b.min.js
|
- https://cdn.shopify.com/s/trekkie.storefront.ebdc6f6e0c97d8f5d6a7dac9bc6ab298fff7cf1b.min.js
|
||||||
```
|
```
|
||||||
|
|
||||||
All of themm are basic scripts with the exception of modernizr. Lets go ahead
|
All of themm are essential scripts with the exception of modernizr. Lets go
|
||||||
and remove modernizr file from the `theam.liquid` file and check that there are
|
ahead and remove modernizr file from the `theam.liquid` file and check that
|
||||||
no errors.
|
there are no errors.
|
||||||
|
|
||||||
We got an error in the `theme.js` file. Lets see if we can fix it by removing
|
We got an error in the `theme.js` file. Lets see if we can fix it by removing
|
||||||
any reference to modernizr.
|
any reference to modernizr.
|
||||||
|
|
||||||
<div class="image__container">
|
<div class="image__container">
|
||||||
<img
|
<img
|
||||||
alt="Lycklig Not Optimized Page Speed Insights Report"
|
alt="Lycklig Modernizr Error"
|
||||||
style="aspect-ratio: 968/895;"
|
style="aspect-ratio: 22/5;"
|
||||||
src="https://res.cloudinary.com/acromatico-development/image/upload/c_scale,f_auto,w_300/v1660926662/Rafa%20Blog/lycklig-initial-test_jz8jly.png"
|
src="https://res.cloudinary.com/acromatico-development/image/upload/c_scale,f_auto,w_300/v1661395373/Rafa%20Blog/lycklig-modernizr_mcanhk.png"
|
||||||
srcset="https://res.cloudinary.com/acromatico-development/image/upload/c_scale,f_auto,w_300/v1660926662/Rafa%20Blog/lycklig-initial-test_jz8jly.png 300w,
|
srcset="https://res.cloudinary.com/acromatico-development/image/upload/c_scale,f_auto,w_300/v1661395373/Rafa%20Blog/lycklig-modernizr_mcanhk.png 300w,
|
||||||
https://res.cloudinary.com/acromatico-development/image/upload/c_scale,f_auto,w_500/v1660926662/Rafa%20Blog/lycklig-initial-test_jz8jly.png 500w,
|
https://res.cloudinary.com/acromatico-development/image/upload/c_scale,f_auto,w_500/v1661395373/Rafa%20Blog/lycklig-modernizr_mcanhk.png 500w,
|
||||||
https://res.cloudinary.com/acromatico-development/image/upload/c_scale,f_auto,w_760/v1660926662/Rafa%20Blog/lycklig-initial-test_jz8jly.png 760w,
|
https://res.cloudinary.com/acromatico-development/image/upload/c_scale,f_auto,w_760/v1661395373/Rafa%20Blog/lycklig-modernizr_mcanhk.png 760w,
|
||||||
https://res.cloudinary.com/acromatico-development/image/upload/c_scale,f_auto,w_968/v1660926662/Rafa%20Blog/lycklig-initial-test_jz8jly.png 968w"
|
https://res.cloudinary.com/acromatico-development/image/upload/c_scale,f_auto,w_968/v1661395373/Rafa%20Blog/lycklig-modernizr_mcanhk.png 968w"
|
||||||
sizes="(max-width: 310px) 300px,
|
sizes="(max-width: 310px) 300px,
|
||||||
(max-width: 510px) 500px,
|
(max-width: 510px) 500px,
|
||||||
(max-width: 768px) 760px,
|
(max-width: 768px) 760px,
|
||||||
(max-width: 1024px) 500px,
|
(max-width: 1024px) 500px,
|
||||||
968px"
|
968px"
|
||||||
/>
|
/>
|
||||||
<small>Lycklig Not Optimized Page Speed Insights Report</small>
|
<small>Lycklig Modernizr Error</small>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
We found a `Modernizr` instance being referenced in diferent parts of the file.
|
We found a `Modernizr` instance being referenced in diferent parts of the file.
|
||||||
We just carefully deleted them and the error was gone. If this had become a
|
We just carefully deleted them and the error was gone. The problem was that all
|
||||||
larger prioblem we woud have gonne back to not removing the modernizr file.
|
the icons of the theme changed to text 👎. This has become a larger prioblem so
|
||||||
|
we will go back to not removing the modernizr file.
|
||||||
|
|
||||||
|
#### Images Optimization and Elements with Layout Shifts
|
||||||
|
|
||||||
|
By looking at the
|
||||||
|
[Web Vitals Webpage Test Report](https://www.webpagetest.org/vitals.php?test=220819_BiDc6R_B5K&run=3#cls)
|
||||||
|
we can see diferent elements that produce layout shifts. The main one is the
|
||||||
|
announcement bar. Lets add a fix height to the announcement bar to fix that
|
||||||
|
issue.
|
||||||
|
|
||||||
|
As well the main logo appears from no where and moves the size of the header. We
|
||||||
|
can add an aspect ratio property to the logo to fix that by adding
|
||||||
|
`aspect-ratio: 10/3;` to the logo style tag.
|
||||||
|
|
||||||
|
Something we noted in the code was that all the images of the theme have lazy
|
||||||
|
loading added, even the initially rendered ones. We removed all the lazuy
|
||||||
|
loading added to the initial images. as well we added a `srcset` attribute and a
|
||||||
|
`sizes` attribute to the images and even some images where still rendered with
|
||||||
|
the CSS `background-image` property, we changed that to be an `img` tag.
|
||||||
|
|
||||||
|
This is the code to render the images of the slider before the changes:
|
||||||
|
|
||||||
|
```html
|
||||||
|
<style>
|
||||||
|
@media screen and (max-width: 1024px) and (max-height: 768px) {
|
||||||
|
.hero__image--{{ block.id }} {
|
||||||
|
background-image: url('{{ block.settings.image | img_url: '1024x1024' | format: 'jpg' }}');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@media screen and (min-width: 1025px), screen and (min-height: 769px) {
|
||||||
|
.hero__image--{{ block.id }} {
|
||||||
|
background-image: url('{{ block.settings.image | img_url: '2048x2048' | format: 'jpg' }}');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<div
|
||||||
|
class="hero__image hero__image--{{ block.id }}"
|
||||||
|
data-image="{{ block.settings.image | img_url: '1024x1024' | format: 'jpg' }}"
|
||||||
|
></div>
|
||||||
|
```
|
||||||
|
|
||||||
|
After we changed the code it looked like this:
|
||||||
|
|
||||||
|
```html
|
||||||
|
<div class="hero__image hero__image--{{ block.id }}">
|
||||||
|
<img
|
||||||
|
srcset="{{ block.settings.image | img_url: '320x320' }} 320w,
|
||||||
|
{{ block.settings.image | img_url: '480x480' }} 480w,
|
||||||
|
{{ block.settings.image | img_url: '800x800' }} 800w,
|
||||||
|
{{ block.settings.image | img_url: '1024x1024' }} 1024w,
|
||||||
|
{{ block.settings.image | img_url: '2048x2048' }} 2048w"
|
||||||
|
sizes="(max-width: 320px) 320px,
|
||||||
|
(max-width: 480px) 480px,
|
||||||
|
(max-width: 800px) 800px,
|
||||||
|
(max-width: 1024px) 1024px,
|
||||||
|
2048px"
|
||||||
|
src="{{ block.settings.image | img_url: '2048x2048' }}"
|
||||||
|
loading="lazy"
|
||||||
|
width="2048"
|
||||||
|
height="2048"
|
||||||
|
alt="{{ block.settings.image.alt | escape }}"
|
||||||
|
class=""
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
```
|
||||||
|
|
||||||
|
### The Final Results
|
||||||
|
|
||||||
|
Over all we think the theme was all ready well optimized, changes where minor
|
||||||
|
and the most relevant change had to do with the slider images. There are other
|
||||||
|
areas of improvement like removing modernizr and jquery from the base libraries
|
||||||
|
the theme uses but that is considered a huge change in which case it would be
|
||||||
|
better to consider migrating to a newer theme.
|
||||||
|
|
||||||
|
The final reports made in Web Page Test ands Google Page Speed Insights are
|
||||||
|
available here:
|
||||||
|
|
||||||
|
- [Web Page Test Report](https://www.webpagetest.org/result/220825_BiDc5H_AXN/)
|
||||||
|
- [Google Page Speed Insights](https://pagespeed.web.dev/report?url=https%3A%2F%2Fwww.lycklig.com.mx%2F)
|
||||||
|
|
||||||
|
Hope this entry helps you optimizing your Shopify Themes, this same concept can
|
||||||
|
be applied to any web page with the difference of the usage of liquid and maybe
|
||||||
|
having more control over the scripts that are being loaded in the page.
|
|
@ -0,0 +1,16 @@
|
||||||
|
import { z, defineCollection } from "astro:content";
|
||||||
|
|
||||||
|
const blogCollection = defineCollection({
|
||||||
|
schema: z.object({
|
||||||
|
layout: z.enum(['../../layouts/main.astro']).optional(),
|
||||||
|
date: z.date(),
|
||||||
|
title: z.string(),
|
||||||
|
description: z.string(),
|
||||||
|
exerpt: z.string(),
|
||||||
|
image: z.string()
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
export const collections = {
|
||||||
|
'blog': blogCollection,
|
||||||
|
};
|
|
@ -49,16 +49,16 @@
|
||||||
"url": "https://github.com/acromatico-development",
|
"url": "https://github.com/acromatico-development",
|
||||||
"icon": "github"
|
"icon": "github"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"name": "Instagram",
|
|
||||||
"url": "https://www.instagram.com/acromatico.dev",
|
|
||||||
"icon": "instagram"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"name": "Discord",
|
"name": "Discord",
|
||||||
"url": "https://discord.gg/NswUaFSG",
|
"url": "https://discord.gg/NswUaFSG",
|
||||||
"icon": "discord"
|
"icon": "discord"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "Instagram",
|
||||||
|
"url": "https://www.instagram.com/acromatico.dev",
|
||||||
|
"icon": "instagram"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "LinkedIn",
|
"name": "LinkedIn",
|
||||||
"url": "https://www.linkedin.com/company/acromatico",
|
"url": "https://www.linkedin.com/company/acromatico",
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
/// <reference path="../.astro/types.d.ts" />
|
||||||
|
/// <reference types="astro/client" />
|
|
@ -5,91 +5,110 @@ import "../styles/base.css";
|
||||||
const profileName = profileData.name;
|
const profileName = profileData.name;
|
||||||
|
|
||||||
const {
|
const {
|
||||||
frontmatter,
|
frontmatter,
|
||||||
title: titleProp,
|
title: titleProp,
|
||||||
description: descriptionProp,
|
description: descriptionProp,
|
||||||
blog,
|
image: imageProp,
|
||||||
|
blog,
|
||||||
|
hasMainTitle,
|
||||||
} = Astro.props;
|
} = Astro.props;
|
||||||
---
|
---
|
||||||
|
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
<link rel="apple-touch-icon" sizes="57x57" href="/apple-icon-57x57.png" />
|
<link rel="apple-touch-icon" sizes="57x57" href="/apple-icon-57x57.png" />
|
||||||
<link rel="apple-touch-icon" sizes="60x60" href="/apple-icon-60x60.png" />
|
<link rel="apple-touch-icon" sizes="60x60" href="/apple-icon-60x60.png" />
|
||||||
<link rel="apple-touch-icon" sizes="72x72" href="/apple-icon-72x72.png" />
|
<link rel="apple-touch-icon" sizes="72x72" href="/apple-icon-72x72.png" />
|
||||||
<link rel="apple-touch-icon" sizes="76x76" href="/apple-icon-76x76.png" />
|
<link rel="apple-touch-icon" sizes="76x76" href="/apple-icon-76x76.png" />
|
||||||
<link rel="apple-touch-icon" sizes="114x114" href="/apple-icon-114x114.png"
|
<link
|
||||||
/>
|
rel="apple-touch-icon"
|
||||||
<link rel="apple-touch-icon" sizes="120x120" href="/apple-icon-120x120.png"
|
sizes="114x114"
|
||||||
/>
|
href="/apple-icon-114x114.png"
|
||||||
<link rel="apple-touch-icon" sizes="144x144" href="/apple-icon-144x144.png"
|
/>
|
||||||
/>
|
<link
|
||||||
<link rel="apple-touch-icon" sizes="152x152" href="/apple-icon-152x152.png"
|
rel="apple-touch-icon"
|
||||||
/>
|
sizes="120x120"
|
||||||
<link rel="apple-touch-icon" sizes="180x180" href="/apple-icon-180x180.png"
|
href="/apple-icon-120x120.png"
|
||||||
/>
|
/>
|
||||||
<link
|
<link
|
||||||
rel="icon"
|
rel="apple-touch-icon"
|
||||||
type="image/png"
|
sizes="144x144"
|
||||||
sizes="192x192"
|
href="/apple-icon-144x144.png"
|
||||||
href="/android-icon-192x192.png"
|
/>
|
||||||
/>
|
<link
|
||||||
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png" />
|
rel="apple-touch-icon"
|
||||||
<link rel="icon" type="image/png" sizes="96x96" href="/favicon-96x96.png" />
|
sizes="152x152"
|
||||||
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png" />
|
href="/apple-icon-152x152.png"
|
||||||
<link rel="manifest" href="/manifest.json" />
|
/>
|
||||||
<meta name="msapplication-TileColor" content="#ffffff" />
|
<link
|
||||||
<meta name="msapplication-TileImage" content="/ms-icon-144x144.png" />
|
rel="apple-touch-icon"
|
||||||
<meta name="theme-color" content="#ffffff" />
|
sizes="180x180"
|
||||||
<meta name="viewport" content="width=device-width" />
|
href="/apple-icon-180x180.png"
|
||||||
<title>
|
/>
|
||||||
{
|
<link
|
||||||
frontmatter?.title
|
rel="icon"
|
||||||
? `${frontmatter?.title} | ${profileName} Blog`
|
type="image/png"
|
||||||
: titleProp
|
sizes="192x192"
|
||||||
? `${titleProp} | ${profileName} Blog`
|
href="/android-icon-192x192.png"
|
||||||
: `${profileName} | Links`
|
/>
|
||||||
}
|
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png" />
|
||||||
</title>
|
<link rel="icon" type="image/png" sizes="96x96" href="/favicon-96x96.png" />
|
||||||
<meta
|
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png" />
|
||||||
name="description"
|
<link rel="manifest" href="/manifest.json" />
|
||||||
content={frontmatter?.description
|
<meta name="msapplication-TileColor" content="#ffffff" />
|
||||||
? frontmatter.description
|
<meta name="msapplication-TileImage" content="/ms-icon-144x144.png" />
|
||||||
: descriptionProp
|
<meta name="theme-color" content="#ffffff" />
|
||||||
? descriptionProp
|
<meta name="viewport" content="width=device-width" />
|
||||||
: profileData.description}
|
<title>
|
||||||
/>
|
{
|
||||||
<meta name="robots" content="index, follow" />
|
frontmatter?.title
|
||||||
<meta property="og:type" content="website" />
|
? `${frontmatter?.title} | ${profileName} Blog`
|
||||||
<meta
|
: titleProp
|
||||||
property="og:title"
|
? `${titleProp} | ${profileName} Blog`
|
||||||
content={frontmatter?.title
|
: `${profileName} | Links`
|
||||||
? `${frontmatter?.title} | ${profileName} Blog`
|
}
|
||||||
: titleProp
|
</title>
|
||||||
? `${titleProp} | ${profileName} Blog`
|
<meta
|
||||||
: `${profileName} | Links`}
|
name="description"
|
||||||
/>
|
content={frontmatter?.description
|
||||||
<meta
|
? frontmatter.description
|
||||||
property="og:description"
|
: descriptionProp
|
||||||
content={frontmatter?.description
|
? descriptionProp
|
||||||
? frontmatter.description
|
: profileData.description}
|
||||||
: descriptionProp
|
/>
|
||||||
? descriptionProp
|
<meta name="robots" content="index, follow" />
|
||||||
: profileData.description}
|
<meta property="og:type" content="website" />
|
||||||
/>
|
<meta
|
||||||
<meta
|
property="og:title"
|
||||||
property="og:image"
|
content={frontmatter?.title
|
||||||
content={frontmatter?.image
|
? `${frontmatter?.title} | ${profileName} Blog`
|
||||||
? frontmatter?.image
|
: titleProp
|
||||||
: "https://res.cloudinary.com/acromatico-development/image/upload/c_fill,f_auto,h_1200,w_1200/v1641392022/Rafa%20Page/6575E4EB-3F86-47E7-A315-9CD51E5279EB_mm7ctf"}
|
? `${titleProp} | ${profileName} Blog`
|
||||||
/>
|
: `${profileName} | Links`}
|
||||||
<meta property="og:url" content={Astro.url} />
|
/>
|
||||||
<link rel="canonical" href={Astro.url} />
|
<meta
|
||||||
|
property="og:description"
|
||||||
|
content={frontmatter?.description
|
||||||
|
? frontmatter.description
|
||||||
|
: descriptionProp
|
||||||
|
? descriptionProp
|
||||||
|
: profileData.description}
|
||||||
|
/>
|
||||||
|
<meta
|
||||||
|
property="og:image"
|
||||||
|
content={frontmatter?.image
|
||||||
|
? frontmatter?.image
|
||||||
|
: imageProp
|
||||||
|
? imageProp
|
||||||
|
: "https://res.cloudinary.com/acromatico-development/image/upload/c_fill,f_auto,h_1200,w_1200/v1641392022/Rafa%20Page/6575E4EB-3F86-47E7-A315-9CD51E5279EB_mm7ctf"}
|
||||||
|
/>
|
||||||
|
<meta property="og:url" content={Astro.url} />
|
||||||
|
<link rel="canonical" href={Astro.url} />
|
||||||
|
|
||||||
<script
|
<script
|
||||||
type="application/ld+json"
|
type="application/ld+json"
|
||||||
set:html={`
|
set:html={`
|
||||||
{
|
{
|
||||||
"@context": "https://schema.org",
|
"@context": "https://schema.org",
|
||||||
"@type": "WebSite",
|
"@type": "WebSite",
|
||||||
|
@ -97,11 +116,11 @@ const {
|
||||||
"url": "https://rafa.page"
|
"url": "https://rafa.page"
|
||||||
}
|
}
|
||||||
`}
|
`}
|
||||||
></script>
|
></script>
|
||||||
|
|
||||||
<script
|
<script
|
||||||
type="application/ld+json"
|
type="application/ld+json"
|
||||||
set:html={`{
|
set:html={`{
|
||||||
"@context": "https://schema.org",
|
"@context": "https://schema.org",
|
||||||
"@type": "Person",
|
"@type": "Person",
|
||||||
"name": "Rafael González Vázquez",
|
"name": "Rafael González Vázquez",
|
||||||
|
@ -113,13 +132,13 @@ const {
|
||||||
],
|
],
|
||||||
"image": "https://res.cloudinary.com/acromatico-development/image/upload/c_fill,f_auto,h_1200,w_1200/v1641392022/Rafa%20Page/6575E4EB-3F86-47E7-A315-9CD51E5279EB_mm7ctf"
|
"image": "https://res.cloudinary.com/acromatico-development/image/upload/c_fill,f_auto,h_1200,w_1200/v1641392022/Rafa%20Page/6575E4EB-3F86-47E7-A315-9CD51E5279EB_mm7ctf"
|
||||||
}`}
|
}`}
|
||||||
></script>
|
></script>
|
||||||
|
|
||||||
{
|
{
|
||||||
frontmatter && (
|
(frontmatter || imageProp) && (
|
||||||
<script
|
<script
|
||||||
type="application/ld+json"
|
type="application/ld+json"
|
||||||
set:html={`
|
set:html={`
|
||||||
{
|
{
|
||||||
"@context": "https://schema.org",
|
"@context": "https://schema.org",
|
||||||
"@type": "NewsArticle",
|
"@type": "NewsArticle",
|
||||||
|
@ -127,12 +146,12 @@ const {
|
||||||
"@type": "WebPage",
|
"@type": "WebPage",
|
||||||
"@id": "${Astro.url}"
|
"@id": "${Astro.url}"
|
||||||
},
|
},
|
||||||
"headline": "${frontmatter.title}",
|
"headline": "${frontmatter?.title || titleProp}",
|
||||||
"image": [
|
"image": [
|
||||||
"${frontmatter.image}"
|
"${frontmatter?.image || imageProp}"
|
||||||
],
|
],
|
||||||
"datePublished": "${frontmatter.date}",
|
"datePublished": "${frontmatter?.date || ""}",
|
||||||
"dateModified": "${frontmatter.date}",
|
"dateModified": "${frontmatter?.date || ""}",
|
||||||
"author": {
|
"author": {
|
||||||
"@type": "Person",
|
"@type": "Person",
|
||||||
"name": "Rafael González Vázquez",
|
"name": "Rafael González Vázquez",
|
||||||
|
@ -140,78 +159,88 @@ const {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`}
|
`}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
<!-- Global site tag (gtag.js) - Google Analytics -->
|
<!-- Global site tag (gtag.js) - Google Analytics -->
|
||||||
<script async src="https://www.googletagmanager.com/gtag/js?id=G-45FLVCCPTZ"
|
<script type="text/partytown" src="https://www.googletagmanager.com/gtag/js?id=G-45FLVCCPTZ"
|
||||||
></script>
|
></script>
|
||||||
<script>
|
<script
|
||||||
// @ts-ignore
|
type="text/partytown"
|
||||||
window.dataLayer = window.dataLayer || [];
|
set:html={`
|
||||||
function gtag() {
|
window.dataLayer = window.dataLayer || [];
|
||||||
// @ts-ignore
|
function gtag() {
|
||||||
dataLayer.push(arguments);
|
dataLayer.push(arguments);
|
||||||
}
|
}
|
||||||
// @ts-ignore
|
gtag("js", new Date());
|
||||||
gtag("js", new Date());
|
gtag("config", "G-45FLVCCPTZ");
|
||||||
// @ts-ignore
|
`}
|
||||||
gtag("config", "G-45FLVCCPTZ");
|
></script>
|
||||||
</script>
|
</head>
|
||||||
</head>
|
|
||||||
|
|
||||||
<body class={`bg-white dark:bg-gray-900`}>
|
<body class={`bg-white dark:bg-gray-900`}>
|
||||||
<header class="w-full flex flex-col justify-center items-center pt-10">
|
<header class="w-full flex flex-col justify-center items-center pt-10">
|
||||||
<img
|
<img
|
||||||
class="w-1/3 md:w-52 rounded-full border-4 border-gray-900 dark:border-white aspect-square"
|
class="w-1/3 md:w-52 rounded-full border-4 border-gray-900 dark:border-white aspect-square"
|
||||||
loading="lazy"
|
loading="lazy"
|
||||||
src="https://res.cloudinary.com/acromatico-development/image/upload/c_fill,f_auto,h_50,w_50/v1641392022/Rafa%20Page/6575E4EB-3F86-47E7-A315-9CD51E5279EB_mm7ctf"
|
src="https://res.cloudinary.com/acromatico-development/image/upload/c_fill,f_auto,h_50,w_50/v1641392022/Rafa%20Page/6575E4EB-3F86-47E7-A315-9CD51E5279EB_mm7ctf"
|
||||||
sizes="(max-width: 640px) 50vw,
|
sizes="(max-width: 640px) 50vw,
|
||||||
208px"
|
208px"
|
||||||
srcset="https://res.cloudinary.com/acromatico-development/image/upload/c_fill,f_auto,h_50,w_50/v1641392022/Rafa%20Page/6575E4EB-3F86-47E7-A315-9CD51E5279EB_mm7ctf 50w,
|
srcset="https://res.cloudinary.com/acromatico-development/image/upload/c_fill,f_auto,h_50,w_50/v1641392022/Rafa%20Page/6575E4EB-3F86-47E7-A315-9CD51E5279EB_mm7ctf 50w,
|
||||||
https://res.cloudinary.com/acromatico-development/image/upload/c_fill,f_auto,h_100,w_100/v1641392022/Rafa%20Page/6575E4EB-3F86-47E7-A315-9CD51E5279EB_mm7ctf 100w,
|
https://res.cloudinary.com/acromatico-development/image/upload/c_fill,f_auto,h_100,w_100/v1641392022/Rafa%20Page/6575E4EB-3F86-47E7-A315-9CD51E5279EB_mm7ctf 100w,
|
||||||
https://res.cloudinary.com/acromatico-development/image/upload/c_fill,f_auto,h_200,w_200/v1641392022/Rafa%20Page/6575E4EB-3F86-47E7-A315-9CD51E5279EB_mm7ctf 200w,
|
https://res.cloudinary.com/acromatico-development/image/upload/c_fill,f_auto,h_200,w_200/v1641392022/Rafa%20Page/6575E4EB-3F86-47E7-A315-9CD51E5279EB_mm7ctf 200w,
|
||||||
https://res.cloudinary.com/acromatico-development/image/upload/c_fill,f_auto,h_600,w_600/v1641392022/Rafa%20Page/6575E4EB-3F86-47E7-A315-9CD51E5279EB_mm7ctf 600w,
|
https://res.cloudinary.com/acromatico-development/image/upload/c_fill,f_auto,h_600,w_600/v1641392022/Rafa%20Page/6575E4EB-3F86-47E7-A315-9CD51E5279EB_mm7ctf 600w,
|
||||||
https://res.cloudinary.com/acromatico-development/image/upload/c_fill,f_auto,h_900,w_900/v1641392022/Rafa%20Page/6575E4EB-3F86-47E7-A315-9CD51E5279EB_mm7ctf 900w,
|
https://res.cloudinary.com/acromatico-development/image/upload/c_fill,f_auto,h_900,w_900/v1641392022/Rafa%20Page/6575E4EB-3F86-47E7-A315-9CD51E5279EB_mm7ctf 900w,
|
||||||
https://res.cloudinary.com/acromatico-development/image/upload/c_fill,f_auto,h_1200,w_1200/v1641392022/Rafa%20Page/6575E4EB-3F86-47E7-A315-9CD51E5279EB_mm7ctf 1200w,
|
https://res.cloudinary.com/acromatico-development/image/upload/c_fill,f_auto,h_1200,w_1200/v1641392022/Rafa%20Page/6575E4EB-3F86-47E7-A315-9CD51E5279EB_mm7ctf 1200w,
|
||||||
https://res.cloudinary.com/acromatico-development/image/upload/c_fill,f_auto,h_1500,w_1500/v1641392022/Rafa%20Page/6575E4EB-3F86-47E7-A315-9CD51E5279EB_mm7ctf 1500w"
|
https://res.cloudinary.com/acromatico-development/image/upload/c_fill,f_auto,h_1500,w_1500/v1641392022/Rafa%20Page/6575E4EB-3F86-47E7-A315-9CD51E5279EB_mm7ctf 1500w"
|
||||||
alt="Rafael González"
|
alt="Rafael González"
|
||||||
/>
|
/>
|
||||||
<h1
|
|
||||||
class="font-mono text-center font-bold underline underline-offset-8 uppercase text-4xl my-4 tracking-wide dark:text-white"
|
{
|
||||||
>
|
hasMainTitle || frontmatter?.title ? (
|
||||||
{profileName}
|
<a href="/">
|
||||||
</h1>
|
<h2 class="font-mono text-center font-bold underline underline-offset-8 uppercase text-4xl my-4 tracking-wide dark:text-white">
|
||||||
<p
|
{profileName} Blog
|
||||||
class="font-mono text-center text-l my-4 sm:mt-4 sm:mb-0 mx-auto w-11/12 max-w-5xl tracking-wide dark:text-white"
|
</h2>
|
||||||
>
|
</a>
|
||||||
{profileData.description}
|
) : (
|
||||||
</p>
|
<a href="/">
|
||||||
<a href="/main.vcf" target="_blank" rel="noopener" class="md:hidden"
|
<h1 class="font-mono text-center font-bold underline underline-offset-8 uppercase text-4xl my-4 tracking-wide dark:text-white">
|
||||||
><button
|
{profileName}
|
||||||
class="mt-4 p-4 bg-black text-white dark:text-black dark:bg-white border-2 border-black rounded-md font-bold uppercase tracking-wide"
|
</h1>
|
||||||
>Agregar a Contactos
|
</a>
|
||||||
</button>
|
)
|
||||||
</a>
|
}
|
||||||
</header>
|
<p
|
||||||
<main
|
class="font-mono text-center text-l my-4 sm:mt-4 sm:mb-0 mx-auto w-11/12 max-w-5xl tracking-wide dark:text-white"
|
||||||
class={`font-mono text-l my-16 sm:mb-8 mx-auto w-11/12 max-w-5xl tracking-wide dark:text-white ${
|
>
|
||||||
blog || frontmatter ? "blog" : ""
|
{profileData.description}
|
||||||
}`}
|
</p>
|
||||||
>
|
<a href="/main.vcf" target="_blank" rel="noopener" class="md:hidden"
|
||||||
<slot />
|
><button
|
||||||
</main>
|
class="mt-4 p-4 bg-black text-white dark:text-black dark:bg-white border-2 border-black rounded-md font-bold uppercase tracking-wide"
|
||||||
<footer class="px-3 py-8">
|
>Agregar a Contactos
|
||||||
<p class="dark:text-white text-center">
|
</button>
|
||||||
Powered by <a
|
</a>
|
||||||
class="underline"
|
</header>
|
||||||
href="https://acromatico.dev"
|
<main
|
||||||
target="_blank"
|
class={`font-mono text-l my-16 sm:mb-8 mx-auto w-11/12 max-w-5xl tracking-wide dark:text-white ${
|
||||||
rel="noopener"
|
blog || frontmatter || imageProp ? "blog" : ""
|
||||||
>Acromático Development
|
}`}
|
||||||
</a>
|
>
|
||||||
</p>
|
<slot />
|
||||||
</footer>
|
</main>
|
||||||
</body>
|
<footer class="px-3 py-8">
|
||||||
|
<p class="dark:text-white text-center">
|
||||||
|
Powered by <a
|
||||||
|
class="underline"
|
||||||
|
href="https://acromatico.dev"
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener"
|
||||||
|
>Acromático Development
|
||||||
|
</a>
|
||||||
|
</p>
|
||||||
|
</footer>
|
||||||
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
---
|
||||||
|
import { getCollection } from 'astro:content';
|
||||||
|
// 1. Generate a new path for every collection entry
|
||||||
|
export async function getStaticPaths() {
|
||||||
|
const blogEntries = await getCollection('blog');
|
||||||
|
return blogEntries.map(entry => ({
|
||||||
|
params: { slug: entry.slug }, props: { entry },
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
// 2. When it's time to render, you can get the entry directly from the prop
|
||||||
|
const { entry } = Astro.props;
|
||||||
|
const { Content } = await entry.render();
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
<Content />
|
|
@ -1,12 +1,15 @@
|
||||||
---
|
---
|
||||||
import MainLayout from "../layouts/main.astro";
|
import MainLayout from "../../layouts/main.astro";
|
||||||
const posts = await Astro.glob("../pages/blog/*.mdx");
|
import {getCollection} from "astro:content";
|
||||||
|
const posts = await getCollection("blog");
|
||||||
|
|
||||||
|
console.log(posts[0].slug);
|
||||||
|
|
||||||
const postByDate = posts
|
const postByDate = posts
|
||||||
.sort((a, b) => {
|
.sort((a, b) => {
|
||||||
return (
|
return (
|
||||||
new Date(b.frontmatter.date).getTime() -
|
new Date(b.data.date).getTime() -
|
||||||
new Date(a.frontmatter.date).getTime()
|
new Date(a.data.date).getTime()
|
||||||
);
|
);
|
||||||
})
|
})
|
||||||
.reverse();
|
.reverse();
|
||||||
|
@ -21,18 +24,18 @@ const postByDate = posts
|
||||||
<section class="grid grid-cols-2 md:grid-cols-4 gap-4">
|
<section class="grid grid-cols-2 md:grid-cols-4 gap-4">
|
||||||
{
|
{
|
||||||
postByDate.map((post) => (
|
postByDate.map((post) => (
|
||||||
<a href={`${post.url}`} class="">
|
<a href={`/blog/${post.slug}`} class="">
|
||||||
<article class="border-2 border-gray-800 dark:border-gray-200 dark:text-gray-200 dark:hover:text-white text-gray-800 hover:text-black">
|
<article class="border-2 border-gray-800 dark:border-gray-200 dark:text-gray-200 dark:hover:text-white text-gray-800 hover:text-black">
|
||||||
<img src={post.frontmatter.image} />
|
<img src={post.data.image} />
|
||||||
<div class="p-4">
|
<div class="p-4">
|
||||||
<h3 class="mb-4 uppercase">
|
<h3 class="mb-4 uppercase">
|
||||||
{post.frontmatter.title}
|
{post.data.title}
|
||||||
</h3>
|
</h3>
|
||||||
<p class="text-s mb-2">
|
<p class="text-s mb-2">
|
||||||
{post.frontmatter.exerpt}
|
{post.data.exerpt}
|
||||||
</p>
|
</p>
|
||||||
<p class="text-s text-gray-600 dark:text-gray-400 text-sm">
|
<p class="text-s text-gray-600 dark:text-gray-400 text-sm">
|
||||||
{new Date(post.frontmatter.date).toLocaleDateString("es-US")}
|
{new Date(post.data.date).toLocaleDateString("es-US")}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</article>
|
</article>
|
|
@ -0,0 +1,85 @@
|
||||||
|
---
|
||||||
|
import MainLayout from "../../layouts/main.astro";
|
||||||
|
import { Client } from "@notionhq/client";
|
||||||
|
import { NotionToMarkdown } from "notion-to-md";
|
||||||
|
import {marked} from "marked";
|
||||||
|
|
||||||
|
const notion = new Client({
|
||||||
|
auth: "secret_AXxqx7iaGrcuAcG5ib9l6smC0jqaEeLDb6G1jtUwI5i",
|
||||||
|
});
|
||||||
|
|
||||||
|
export async function getStaticPaths() {
|
||||||
|
const pageId = "87ff5ccc453349de8aa5ae32833817e3";
|
||||||
|
|
||||||
|
const notionPagesContent = await (
|
||||||
|
await fetch(
|
||||||
|
`https://api.notion.com/v1/blocks/${pageId}/children?page_size=100`,
|
||||||
|
{
|
||||||
|
headers: {
|
||||||
|
Authorization: `Bearer secret_AXxqx7iaGrcuAcG5ib9l6smC0jqaEeLDb6G1jtUwI5i`,
|
||||||
|
"Notion-Version": "2022-02-22",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
).json();
|
||||||
|
|
||||||
|
const pages = notionPagesContent.results.filter(
|
||||||
|
(page) => page.type === "child_page"
|
||||||
|
);
|
||||||
|
|
||||||
|
return pages.map((page) => ({
|
||||||
|
params: {
|
||||||
|
id: page.id,
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
const { id } = Astro.params;
|
||||||
|
|
||||||
|
const pageData = await (
|
||||||
|
await fetch(`https://api.notion.com/v1/pages/${id}`, {
|
||||||
|
headers: {
|
||||||
|
Authorization: `Bearer secret_AXxqx7iaGrcuAcG5ib9l6smC0jqaEeLDb6G1jtUwI5i`,
|
||||||
|
"Notion-Version": "2022-02-22",
|
||||||
|
},
|
||||||
|
})
|
||||||
|
).json();
|
||||||
|
|
||||||
|
const n2m = new NotionToMarkdown({ notionClient: notion });
|
||||||
|
|
||||||
|
// @ts-ignore
|
||||||
|
const mdblocks = await n2m.pageToMarkdown(id);
|
||||||
|
const mdString = n2m.toMarkdownString(mdblocks);
|
||||||
|
const generalString = mdString.replace(/(\r\n|\n|\r)/gm, " ").replace(/(-|#)/gm, "").replaceAll(" ", " ");
|
||||||
|
const mdArray = mdString.split("\n");
|
||||||
|
|
||||||
|
for (let i = 0; i < mdArray.length; i++) {
|
||||||
|
if (mdArray[i].includes("https://www.youtube.com")) {
|
||||||
|
const videoId = mdArray[i].split("watch?v=")[1].split("&")[0];
|
||||||
|
mdArray[i] = '<iframe id="' + videoId + '" type="text/html" width="720" height="405" src="https://www.youtube.com/embed/' + videoId + '" frameborder="0" allowfullscreen></iframe>';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const mdGood = mdArray.join("\n");
|
||||||
|
|
||||||
|
const htmlData = marked.parse(mdGood);
|
||||||
|
|
||||||
|
const title = pageData.properties.title.title[0].plain_text.split(" | ").splice(0, pageData.properties.title.title[0].plain_text.split(" | ").length - 1).join(" - ");
|
||||||
|
const description = generalString.substring(0, 250);
|
||||||
|
console.log(pageData.cover)
|
||||||
|
const image = pageData.cover.external.url;
|
||||||
|
---
|
||||||
|
|
||||||
|
<MainLayout
|
||||||
|
title={title}
|
||||||
|
description={description}
|
||||||
|
image={image}
|
||||||
|
blog={false}
|
||||||
|
hasMainTitle={true}
|
||||||
|
>
|
||||||
|
<div class="relative w-full aspect-video flex justify-center items-center mb-4">
|
||||||
|
<img src={image} alt={title} class="w-full h-full object-cover absolute top-0 left-0">
|
||||||
|
<h1 class="z-10 text-white px-8 text-sm md:text-xl m-0">{title}</h1>
|
||||||
|
</div>
|
||||||
|
<div set:html={htmlData}></div>
|
||||||
|
</MainLayout>
|
|
@ -0,0 +1,57 @@
|
||||||
|
---
|
||||||
|
import MainLayout from "../../layouts/main.astro";
|
||||||
|
|
||||||
|
const pageId = "87ff5ccc453349de8aa5ae32833817e3";
|
||||||
|
|
||||||
|
const notionPageData = await (
|
||||||
|
await fetch(`https://api.notion.com/v1/pages/${pageId}`, {
|
||||||
|
headers: {
|
||||||
|
Authorization: `Bearer secret_AXxqx7iaGrcuAcG5ib9l6smC0jqaEeLDb6G1jtUwI5i`,
|
||||||
|
"Notion-Version": "2022-02-22",
|
||||||
|
},
|
||||||
|
})
|
||||||
|
).json();
|
||||||
|
|
||||||
|
const notionPageContent = await (
|
||||||
|
await fetch(
|
||||||
|
`https://api.notion.com/v1/blocks/${pageId}/children?page_size=100`,
|
||||||
|
{
|
||||||
|
headers: {
|
||||||
|
Authorization: `Bearer secret_AXxqx7iaGrcuAcG5ib9l6smC0jqaEeLDb6G1jtUwI5i`,
|
||||||
|
"Notion-Version": "2022-02-22",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
).json();
|
||||||
|
|
||||||
|
const title = notionPageData.properties.title.title[0].plain_text;
|
||||||
|
|
||||||
|
const pages = notionPageContent.results.filter(
|
||||||
|
(page) => page.type === "child_page"
|
||||||
|
);
|
||||||
|
---
|
||||||
|
|
||||||
|
<MainLayout
|
||||||
|
title={title}
|
||||||
|
description="Aquí pordrás encontrar una lista de todas las notas de clases que he dado y sermones que he escuchado."
|
||||||
|
blog={false}
|
||||||
|
>
|
||||||
|
<h1 class="text-4xl text-center uppercase font-bold mb-8">
|
||||||
|
Nots de Clases y Sermones de Rafa
|
||||||
|
</h1>
|
||||||
|
<h2 class="text-3xl font-bold mb-4">{title}</h2>
|
||||||
|
<section class="grid grid-cols-2 md:grid-cols-4 gap-4">
|
||||||
|
{
|
||||||
|
pages.map((page) => (
|
||||||
|
<div>
|
||||||
|
<a href={`/church/${page.id}`}>
|
||||||
|
|
||||||
|
<h3 class="text-xl">
|
||||||
|
{page.child_page.title}
|
||||||
|
</h3>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
))
|
||||||
|
}
|
||||||
|
</section>
|
||||||
|
</MainLayout>
|
|
@ -38,7 +38,7 @@ for (let link of profileData.profesionalLinks) {
|
||||||
<div class="grid grid-cols-2 md:grid-cols-4 gap-4 w-11/12 max-w-5xl my-2 mx-auto">
|
<div class="grid grid-cols-2 md:grid-cols-4 gap-4 w-11/12 max-w-5xl my-2 mx-auto">
|
||||||
|
|
||||||
{personalLinks.map(perLink => (
|
{personalLinks.map(perLink => (
|
||||||
<Icon client:load perLink={perLink} profileName={profileName} />
|
<Icon client:load perLink={perLink} profileName={profileName} />
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
<h2 class="font-mono font-bold uppercase text-xl my-14 mx-auto tracking-wide w-11/12 max-w-5xl dark:text-white">
|
<h2 class="font-mono font-bold uppercase text-xl my-14 mx-auto tracking-wide w-11/12 max-w-5xl dark:text-white">
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
@tailwind components;
|
@tailwind components;
|
||||||
@tailwind utilities;
|
@tailwind utilities;
|
||||||
|
|
||||||
@layer utilities {
|
@layer components {
|
||||||
main.blog h1 {
|
main.blog h1 {
|
||||||
@apply text-4xl font-bold mb-8 text-center uppercase;
|
@apply text-4xl font-bold mb-8 text-center uppercase;
|
||||||
}
|
}
|
||||||
|
@ -28,6 +28,10 @@
|
||||||
@apply list-disc mb-8 ml-8;
|
@apply list-disc mb-8 ml-8;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
main.blog li p {
|
||||||
|
@apply mb-0;
|
||||||
|
}
|
||||||
|
|
||||||
main.blog li:not(:last-child) {
|
main.blog li:not(:last-child) {
|
||||||
@apply mb-4;
|
@apply mb-4;
|
||||||
}
|
}
|
||||||
|
@ -86,4 +90,14 @@
|
||||||
main.blog pre .language-id {
|
main.blog pre .language-id {
|
||||||
@apply w-full;
|
@apply w-full;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
main.blog iframe {
|
||||||
|
@apply w-full mb-8;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media only screen and (max-width: 768px) {
|
||||||
|
main.blog h1 {
|
||||||
|
@apply text-lg m-0;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
{
|
||||||
|
// Note: No change needed if you use "astro/tsconfigs/strict" or "astro/tsconfigs/strictest"
|
||||||
|
"extends": "astro/tsconfigs/base",
|
||||||
|
"compilerOptions": {
|
||||||
|
"strictNullChecks": true
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue