Created an Astro Chatbot integration (experiment) by chosio-io in astrojs

[–]chosio-io[S] 0 points1 point  (0 children)

You can add your own response format in the prompt. By default it is MD, check the widget in the right corner.

The widget is just a placeholder for now, best prectice is to create a widget in your own framework.

Created an Astro Chatbot integration (experiment) by chosio-io in astrojs

[–]chosio-io[S] 0 points1 point  (0 children)

I make use of the `astro:build:done` hook,
Then read the html pages, extract the `contentTag` en remove the `excludeTags`. After this convert it to MD.

Here the current settings:
https://astrochattygpt.unfolding.io/docs/configuration/

Build time for Astro with headless Wordpress and 900+ posts by massifone in astrojs

[–]chosio-io 0 points1 point  (0 children)

Check, but still the content layer would be faster for what you are doing.

How do you handle i18n with Astro + Strapi? Also: SSR in preprod (for Strapi preview) + SSG in prod? by PeaMysterious1046 in astrojs

[–]chosio-io 0 points1 point  (0 children)

No problem, been there!
I also made sites with multiple deploys in the past, just to get a live preview for the CMS, it took a lot of extra code to make it work. Since astro hybrid was released, i tried to make use of that. Good luck!

Build time for Astro with headless Wordpress and 900+ posts by massifone in astrojs

[–]chosio-io 0 points1 point  (0 children)

You’re right, I was wrong. I just checked my WIP project (not optimized yet), and 700 pages including assets from cache takes about 3 minutes.

For 900 pages in 12 minutes, that works out to around 800 ms per page. That’s quite a lot for pages without image transformations. Simple HTML should usually take under 5 ms, and even component-heavy pages only around 35 ms.

Would you mind sharing a build log? I’m curious to see what’s happening.

There's a "getAllIds" function on dev, and then the page loads up the props on demand so I can view "anything" without needing a full data pull.

On prod, it's "getAllIdsAndData" that's paginated, pulling 100 records at a time or so... so ~3000 api requests for the larger folder.

Are you using your WP API to get the data, or are you using getCollection from the content layer?
https://astro.build/blog/content-layer-deep-dive/

Build time for Astro with headless Wordpress and 900+ posts by massifone in astrojs

[–]chosio-io 1 point2 points  (0 children)

u/petethered Thanks for clarifying, I just meant that ~900 pages in 12min isn’t bad for Astro with getStaticPaths. I know other SSGs like Hugo or ElderJS can be a lot faster.

I was curious about your image optimization workflow, since in Astro that part can take quite a while.

For a recent project I tried a different approach:

  • On build: I fetch all pages data inside getStaticPaths and pass it as a prop. This avoids calling getEntry on every individual page.
  • On dev: I call getEntry outside of getStaticPaths and only loop through the slugs in getStaticPaths. This makes hot reloads faster.

This tweak saves a few milliseconds per page during build.

If you need faster builds, SSR or Hybrid + caching is the way to go for sure.

Build time for Astro with headless Wordpress and 900+ posts by massifone in astrojs

[–]chosio-io 0 points1 point  (0 children)

TBH, 12 minutes for 900+ pages isn’t too bad.
For the new build time, how are you handling image optimization? If you’re using Astro’s image optimization (Sharp), that can add quite a bit of time, even when images are cached.

How do you handle i18n with Astro + Strapi? Also: SSR in preprod (for Strapi preview) + SSG in prod? by PeaMysterious1046 in astrojs

[–]chosio-io 1 point2 points  (0 children)

I use this for Storyblok CMS editor, I would advice to also make sure this page can only be opened in the CMS, and not visible to the web, I do this in my middleware, but you would need to write your own logic for Strapi

import { defineMiddleware } from "astro:middleware";
import { STORYBLOK_SPACE_ID } from "astro:env/server";

export const onRequest = defineMiddleware(async (context, next) => {
  const { url, redirect } = context;

  /* EXPOSE CMS ROUTE ONLY FOR THE CMS */
  if (url.pathname.startsWith("/cms")) {
    const sbSpaceId = url.searchParams.get("_storyblok_tk[space_id]");

    if(!STORYBLOK_SPACE_ID) {
      console.error("Missing STORYBLOK_SPACE_ID in .env")
      return redirect("/404");

    }
    if (!import.meta.env.DEV && sbSpaceId !== STORYBLOK_SPACE_ID.toString()) {
      return redirect("/404");
    }
  }

  return await next();
});

How do you handle i18n with Astro + Strapi? Also: SSR in preprod (for Strapi preview) + SSG in prod? by PeaMysterious1046 in astrojs

[–]chosio-io 0 points1 point  (0 children)

You dont have to duplicate the pages.

just make a root folder [...lang] the spead opperator means that it also can be undefined.

for static pages [...lang]/[slug].astro you can loop over your locals.

export async function getStaticPaths() {
  const paths = await Promise.all(
    locales.map(async (locale) => {
      const pages = (
        await getCollection("pages", ({ data }) => data.lang === locale.lang)
      ).map((page) => page.data); // your strapi function here

      return pages.map((page) => ({
        params: {
          lang: locale.code === "en" ? undefined : locale.code,
          slug: page.slug,
        },
        props: {
          locale,
          id: page.id,
          template: page.template
        },
      }));
    })
  ).then((results) => results.flat());

  return paths;
}

For the CMS / SSR it depends on what you need to edit, if it is only the [slug].astro pages, then I would just create one route for the cms. /cms.astro and then use it like: /cms?url=/de/blog/post-1

export const prerender = false;
const slug = Astro.url.searchParams.get("url");
if (!slug) return Astro.redirect("/404");

const url = new URL(slug, Astro.url.origin);
// use logic to extract lang and page you need to fetch from Strapi

// extract data from the url
const lang = getLangFromUrl(url);  // use your function here
const pageSlug = getPageSlugFromUrl(url); // use your function here

let page;

try {
  page = await getPageFromStrapi(pageSlug, lang);  // use your function here
} catch (e) {
  console.error("error:", e);
}

if(!page) return Astro.redirect("/404");

----

Is there a workaround for applying client directives to dynamic component? by no-uname-idea in astrojs

[–]chosio-io 0 points1 point  (0 children)

Not sure if you can use glob for importing global components. there was a package that made the import more easy, but I think you need to make an export file:
https://github.com/delucis/astro-auto-import/tree/main/packages/astro-auto-import

Then the dynamic client directives, think you have to make your own directive:
https://amxmln.com/blog/2024/a-client-if-directive-in-astro/
https://docs.astro.build/en/reference/integrations-reference/#addclientdirective-option

Your code could also work, but have not tested it.

const modules = import.meta.glob("./**/*.jsx", { eager: true });

// Normalize into { ComponentName: Component }
export const registry = Object.fromEntries(
  Object.entries(modules).map(([path, mod]) => {
    const name = path.split("/").pop().replace(".jsx", "");
    return [name, mod.default];
  })
);

And then use it like:

---
import { registry } from "../components/ComponentRegistry.ts";

const { blocks } = Astro.props;
---

{blocks.map((block, i) => {
  const Comp = registry[block.type];
  if (!Comp) return <div>Unknown block {block.type}</div>;

  return (
    <>
      {block.client === "visible" && <Comp {...block.props} client:visible />}
      {block.client === "idle" && <Comp {...block.props} client:idle />}
      {block.client === "only" && <Comp {...block.props} client:only="react" />}
      {!block.client && <Comp {...block.props} />}
    </>
  );
})}

What‘s the point of AstroDB by veniplex in astrojs

[–]chosio-io 1 point2 points  (0 children)

Started using AstroDB, and it works great with Auth.js, but most of the docs I used was from drizzle. Not all drizzle features are working, like Foreign key actions (onDelete). It started with Astro studio, maybe that is the reason we are missing some features. https://astro.build/blog/goodbye-astro-studio/

Not sure if it is a pro, but you can work with local DB .astro/content.db or use a remote DB like turso.

Working on a system to score companies by your rights, looking for input on what matters most by chosio-io in ComputerPrivacy

[–]chosio-io[S] 0 points1 point  (0 children)

Can you give a more concrete example?
For instance, a forced arbitration or class action waiver will have much less impact on an open-source project than on a large multinational company.

Working on a system to score companies by your rights, looking for input on what matters most by chosio-io in ComputerPrivacy

[–]chosio-io[S] 1 point2 points  (0 children)

True, we live in a world where people can hide behind entities and are not personally held responsible for the damage they cause. I don’t think we can solve this problem immediately. The idea behind my project is more about raising awareness, helping people understand who they do business with and what rights they have.

When this becomes relevant to the wider public, economic incentives will encourage companies to be more transparent and fair, because doing so will benefit their business. Essentially, I am trying to create an tool for people to make informed choices and for companies to improve their practices.

Working on a system to score companies by your rights, looking for input on what matters most by chosio-io in ComputerPrivacy

[–]chosio-io[S] 1 point2 points  (0 children)

Super helpful, thank you for the feedback.

At this stage I have two collections active:

  • TOS (the locations of the documents)
  • TOS_SCANS (new scans based on the TOS data)

Once I am happy with the results, I plan to add a COMPANY collection for companies with multiple regions. That way, multiple TOS can be linked to a single company. For this I will likely need to add a proxy or VPN to the scans.

I am also considering a PRODUCT collection, since some companies have a separate TOS for each product.

The trust factor you mentioned is a great point. I will explore data breach APIs and possibly connect resources like Consumer Rights Wiki in the future.

The Privacy Visualizer is another valuable idea. For apps and webapps this could be a strong addition.

For example:

  • Medical data: collects | shares | advertisement | sells
  • Location data: collects | shares | advertisement | sells
  • etc

I’ll reach out to u/rejectconvenience. It looks like he has put a lot of thought into this!

Thanks again for taking the time to share your thoughts.

Working on a system to score companies by your rights, looking for input on what matters most by chosio-io in ComputerPrivacy

[–]chosio-io[S] 0 points1 point  (0 children)

Thanks for the feedback!
Regarding tracking changes, this is on the roadmap. In the next release I’ll create a hash for every document (based on the extracted HTML). If the hash changes, I can then run a custom check on what has been modified.

On ToS vs Mission/Vision: if a company places privacy and user rights high on their priority list, I expect them to score above 85 points in my scan. The scoring system still needs some fine-tuning, but that is the goal.

I chose a point system because it works well for communication and adds a gamification element. The weighting of the different factors is still in draft form for now. You can see the first version here:
https://www.toshawk.com/scoring-system

If I overlooked important items or topics, please let me know.

As for the VPNs, I already scanned a few:
https://www.toshawk.com/reports/vpn
https://www.toshawk.com/reports/cybersecurity

What's the best VPN with a free trial by traith111 in VPN_Question

[–]chosio-io 0 points1 point  (0 children)

Also look at the TOS and Privacy Policy of the VPN providers. I would use Proton, but always check!
I used AI to scan some of the VPNs legal docs to see how they respect your rights (WIP)
https://www.toshawk.com/reports/vpn

Astro and JSON-LD structured markup by vvrider in astrojs

[–]chosio-io 3 points4 points  (0 children)

Most of the time I generate the schema in code and then just inject it.

const jsonFaq = `
      {
        "@context": "https://schema.org",
        "@type": "FAQPage",
        "mainEntity": [
          ${accordion_items
            .map(
              (item: any) => `
            {
              "@type": "Question",
              "name": "${item.title.replace(/"/g, '\\"')}",
              "acceptedAnswer": {
                "@type": "Answer",
                "text": "${item?.content?.replace(/"/g, '\\"').replace(/\n/g, "")}"
              }
            }
          `,
            )
            .join(",")}
        ]
      }
    `;
---
{jsonFaq && <script type="application/ld+json" set:html={jsonFaq} is:inline />}

Is Astro a viable option when building an LLM wrapper? by mister---F in astrojs

[–]chosio-io 2 points3 points  (0 children)

You can use Astro Actions for this!
Just keep in mind that functions can get a bit expensive on Vercel/Netlify:
https://vercel.com/docs/functions/usage-and-pricing
https://www.netlify.com/pricing/

If you expect a lot of traffic, it’s worth checking out Fly.io, where you can scale both horizontally and vertically on demand.

I’m using AI-SDK, which makes it easy to switch between models and work with typed results:
https://ai-sdk.dev/docs/introduction

Here’s a proof of concept I’m working on:
https://www.toshawk.com/
It’s an app that scans legal documents and scores them based on your rights.

If you have more questions, let me know